diff --git a/.github/workflows/gitlab.yml b/.github/workflows/gitlab.yml new file mode 100644 index 0000000000000000000000000000000000000000..aac739274eb8946eee49f8568f7b290a0564a5db --- /dev/null +++ b/.github/workflows/gitlab.yml @@ -0,0 +1,19 @@ +name: GitlabSync + +on: + - push + - delete + +jobs: + sync: + runs-on: ubuntu-latest + name: Git Repo Sync + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + - uses: wangchucheng/git-repo-sync@v0.1.0 + with: + target-url: ${{ secrets.GITLAB_TARGET_URL }} + target-username: ${{ secrets.GITLAB_TARGET_USERNAME }} + target-token: ${{ secrets.GITLAB_TARGET_TOKEN }} \ No newline at end of file diff --git a/Gemfile b/Gemfile index 8358008487f8378a7c17b05628d12b9ffb69a25f..a1eae116bce4500a9144a9e65503c69cb76cdff1 100644 --- a/Gemfile +++ b/Gemfile @@ -27,7 +27,6 @@ gem "enum_help" gem "faceted_search" gem "font-awesome-sass" gem "front_matter_parser" -gem "gdpr", "~> 1.2.5" gem "geocoder", "~> 1.8" gem "geo_point" gem "gitlab" diff --git a/Gemfile.lock b/Gemfile.lock index 093d7a859f6986a54e4aff65d117d93370bc2a47..a93bf9338577c783ee930fcacd32ed6240440ff5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -93,7 +93,7 @@ GEM i18n (>= 1.6, < 2) minitest (>= 5.1) tzinfo (~> 2.0) - addressable (2.8.2) + addressable (2.8.3) public_suffix (>= 2.0.2, < 6.0) angularjs-rails (1.8.0) annotate (3.2.0) @@ -102,7 +102,7 @@ GEM autoprefixer-rails (10.4.13.0) execjs (~> 2) aws-eventstream (1.2.0) - aws-partitions (1.740.0) + aws-partitions (1.742.0) aws-sdk-core (3.171.0) aws-eventstream (~> 1, >= 1.0.2) aws-partitions (~> 1, >= 1.651.0) @@ -111,7 +111,7 @@ GEM aws-sdk-kms (1.63.0) aws-sdk-core (~> 3, >= 3.165.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.120.0) + aws-sdk-s3 (1.120.1) aws-sdk-core (~> 3, >= 3.165.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.4) @@ -224,10 +224,6 @@ GEM font-awesome-sass (6.4.0) sassc (~> 2.0) front_matter_parser (1.0.1) - gdpr (1.2.5) - js_cookie_rails - rails - sassc-rails geo_calc (0.7.8) activesupport (>= 3.0.1) geo_units (~> 0.3.2) @@ -279,8 +275,6 @@ GEM thor (>= 0.14, < 2.0) jquery-ui-rails (6.0.1) railties (>= 3.2.16) - js_cookie_rails (2.2.0) - railties (>= 3.1) json (2.6.3) jwt (2.7.0) kamifusen (1.11.2) @@ -588,7 +582,6 @@ DEPENDENCIES figaro font-awesome-sass front_matter_parser - gdpr (~> 1.2.5) geo_point geocoder (~> 1.8) gitlab diff --git a/app/assets/images/communication/blocks/templates/features.jpg b/app/assets/images/communication/blocks/templates/features.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6c32f7e0dac707c1b58cf3c5f02ed8339cdd4096 Binary files /dev/null and b/app/assets/images/communication/blocks/templates/features.jpg differ diff --git a/app/assets/images/communication/blocks/templates/posts/alternate.png b/app/assets/images/communication/blocks/templates/posts/alternate.png new file mode 100644 index 0000000000000000000000000000000000000000..0e3517906860abe0f2bf69cde13750917ac839c9 Binary files /dev/null and b/app/assets/images/communication/blocks/templates/posts/alternate.png differ diff --git a/app/assets/javascripts/admin/appstack.js b/app/assets/javascripts/admin/appstack.js index eea9af01b78b0bd2d79035316b5dc8b2c4bd094f..cd460cea74caa81e28e1a514ca9cbb7473cccdb9 100644 --- a/app/assets/javascripts/admin/appstack.js +++ b/app/assets/javascripts/admin/appstack.js @@ -8,7 +8,6 @@ //= require cropperjs/dist/cropper //= require jquery-cropper/dist/jquery-cropper //= require appstack/app -//= require gdpr/cookie_consent //= require sortablejs/Sortable //= require summernote/summernote-bs5 //= require slug/slug diff --git a/app/assets/javascripts/admin/pure.js b/app/assets/javascripts/admin/pure.js index 00c97d27fd4b2f11e65cae02ff8802e0d6ef27fd..4cc380290368a53cb9caebe40eb3a841c4c31d36 100644 --- a/app/assets/javascripts/admin/pure.js +++ b/app/assets/javascripts/admin/pure.js @@ -9,7 +9,6 @@ //= require jquery-cropper/dist/jquery-cropper // TODO remove appstack js //= require appstack/app -//= require gdpr/cookie_consent //= require sortablejs/Sortable //= require summernote/summernote-bs5 //= require slug/slug diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 19545a0bccd3fa9908e5b35280ed224190b74b3e..e8a0f2e802bc126febf0934d16a09fd55818ac04 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -8,7 +8,6 @@ //= require simple_form_password_with_hints //= require simple_form_bs5_file_input //= require summernote/summernote-bs5 -//= require gdpr/cookie_consent //= require autocomplete-rails //= require_tree ./application/plugins //= require_self diff --git a/app/assets/javascripts/devise.js b/app/assets/javascripts/devise.js index 26efc2d665f4a7e902f56e9075c6baec61b83df2..87f4ad18ee3ead168bb2e72b76cfb736557c7246 100644 --- a/app/assets/javascripts/devise.js +++ b/app/assets/javascripts/devise.js @@ -8,7 +8,6 @@ //= require simple_form_bs5_file_input //= require cropperjs/dist/cropper //= require jquery-cropper/dist/jquery-cropper -//= require gdpr/cookie_consent //= require_self //= require_tree ./admin/plugins diff --git a/app/assets/javascripts/extranet.js b/app/assets/javascripts/extranet.js index acfd1811ba7440b3a839c8868adee361bf550d1c..f82a3bacb14d7873d0bef0c38bd5f1f2832cafc4 100644 --- a/app/assets/javascripts/extranet.js +++ b/app/assets/javascripts/extranet.js @@ -10,7 +10,6 @@ //= require simple_form_password_with_hints //= require simple_form_bs5_file_input //= require summernote/summernote-bs5 -//= require gdpr/cookie_consent //= require autocomplete-rails //= require_tree ./application/plugins //= require_tree ./extranet diff --git a/app/assets/stylesheets/admin/appstack.sass b/app/assets/stylesheets/admin/appstack.sass index 3413526ba440914d25ccfa8aea3f2e44d45ddf3e..d2a849435d0051d3cd1b00934fd699d71e0f826d 100644 --- a/app/assets/stylesheets/admin/appstack.sass +++ b/app/assets/stylesheets/admin/appstack.sass @@ -6,7 +6,6 @@ @import 'simple_form_bs5_file_input' @import 'summernote-bs5' @import 'cropperjs/dist/cropper' -@import 'gdpr/cookie_consent' @import 'codemirror/lib/codemirror' @import '../commons/*' @import 'commons/*' diff --git a/app/assets/stylesheets/admin/pure.sass b/app/assets/stylesheets/admin/pure.sass index 0b29efb7e3f0b6037ceba282053169f3b6cdaf67..b3638de514982db5fb02d87543400830c493721b 100644 --- a/app/assets/stylesheets/admin/pure.sass +++ b/app/assets/stylesheets/admin/pure.sass @@ -10,7 +10,6 @@ @import 'simple_form_bs5_file_input' @import 'summernote-bs5' @import 'cropperjs/dist/cropper' -@import 'gdpr/cookie_consent' @import 'codemirror/lib/codemirror' @import '../commons/*' @import 'commons/*' diff --git a/app/assets/stylesheets/admin/pure/grid.sass b/app/assets/stylesheets/admin/pure/grid.sass index ff028e0fa6d911a7dcd4b07f1e27b0b81f0e0ad6..ffdb47b85b9d4a40d07889a70e80e9d6f0ad4053 100644 --- a/app/assets/stylesheets/admin/pure/grid.sass +++ b/app/assets/stylesheets/admin/pure/grid.sass @@ -1,4 +1,4 @@ * --bs-gutter-x: 64px !important @media (max-width: 768px) - --bs-gutter-x: 20px !important + --bs-gutter-x: 32px !important diff --git a/app/assets/stylesheets/application.sass b/app/assets/stylesheets/application.sass index cbdad2dd5161fd3e130203aabb7e325e41f39451..407658cd3780ab5ca9bb1ff60e3db4f77441fd70 100644 --- a/app/assets/stylesheets/application.sass +++ b/app/assets/stylesheets/application.sass @@ -3,7 +3,6 @@ @import 'simple_form_password_with_hints' @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/extranet.sass b/app/assets/stylesheets/extranet.sass index 7beab43bb867d71afd0fe6afdbf4e304fc0976d3..de4182540a5c480f4ce792507521b2e02d6ebb41 100644 --- a/app/assets/stylesheets/extranet.sass +++ b/app/assets/stylesheets/extranet.sass @@ -6,7 +6,6 @@ @import 'simple_form_password_with_hints' @import 'simple_form_bs5_file_input' @import 'summernote-bs5' -@import 'gdpr/cookie_consent' @import 'cropperjs/dist/cropper' @import 'commons/summernote' @import 'commons/bootstrap-icons' diff --git a/app/assets/stylesheets/extranet/pages/_posts.sass b/app/assets/stylesheets/extranet/pages/_posts.sass index 1d785f2606e0a2728bddb1c9a6375ea115529736..6eea8a17340e00de999c521dbfbdfe9291891dab 100644 --- a/app/assets/stylesheets/extranet/pages/_posts.sass +++ b/app/assets/stylesheets/extranet/pages/_posts.sass @@ -1,10 +1,6 @@ .posts-show header figure position: relative - @include media-breakpoint-up(md) - display: inline-block - padding-left: 2.813rem - width: 25% picture img width: 100% &.with-credit::after diff --git a/app/models/communication/block.rb b/app/models/communication/block.rb index 7bfc5a3bf480fb675e78a095548ef6710f333900..eefa859355215106632fcb614c7c71c49ff2452a 100644 --- a/app/models/communication/block.rb +++ b/app/models/communication/block.rb @@ -12,23 +12,20 @@ # created_at :datetime not null # updated_at :datetime not null # about_id :uuid indexed => [about_type] -# heading_id :uuid indexed # university_id :uuid not null, indexed # # Indexes # -# index_communication_blocks_on_heading_id (heading_id) # index_communication_blocks_on_university_id (university_id) # index_communication_website_blocks_on_about (about_type,about_id) # # Foreign Keys # # fk_rails_18291ef65f (university_id => universities.id) -# fk_rails_90ac986fab (heading_id => communication_block_headings.id) # class Communication::Block < ApplicationRecord include Accessible - include WithConnections + include AsIndirectObject include WithPosition include WithUniversity include Sanitizable @@ -42,12 +39,19 @@ class Communication::Block < ApplicationRecord # template_blobs would be a better name, because there are files has_many_attached :template_images + # Les numĆ©ros sont un peu en vrac + # Dans l'idĆ©e, pour le futur + # 1000 basic + # 2000 storytelling + # 3000 references + # 4000 utilities enum template_kind: { chapter: 50, image: 51, gallery: 300, video: 52, key_figures: 56, + features: 2010, datatable: 54, files: 55, embed: 53, @@ -65,14 +69,13 @@ class Communication::Block < ApplicationRecord CATEGORIES = { basic: [:chapter, :image, :video, :datatable], - storytelling: [:key_figures, :gallery, :call_to_action, :testimonials, :timeline], + storytelling: [:key_figures, :features, :gallery, :call_to_action, :testimonials, :timeline], references: [:pages, :posts, :organization_chart, :partners, :programs], utilities: [:files, :definitions, :embed, :contact] } scope :published, -> { where(published: true) } - after_save :sync_if_about_is_direct before_save :attach_template_blobs before_validation :set_university_from_about, on: :create @@ -146,10 +149,6 @@ class Communication::Block < ApplicationRecord "Communication::Block::Template::#{template_kind.classify}".constantize end - def sync_if_about_is_direct - about.save_and_sync if about.respond_to? :save_and_sync - end - # FIXME @sebou # Could not find or build blob: expected attachable, got #<ActiveStorage::Blob id: "f4c78657-5062-416b-806f-0b80fb66f9cd", key: "gri33wtop0igur8w3a646llel3sd", filename: "logo.svg", content_type: "image/svg+xml", metadata: {"identified"=>true, "width"=>709, "height"=>137, "analyzed"=>true}, service_name: "scaleway", byte_size: 4137, checksum: "aZqqTYabP5+72ZeddcZ/2Q==", created_at: "2022-05-05 12:17:33.941505000 +0200", university_id: "ebf2d273-ffc9-4d9f-a4ee-a2146913d617"> def attach_template_blobs diff --git a/app/models/communication/block/template/feature.rb b/app/models/communication/block/template/feature.rb new file mode 100644 index 0000000000000000000000000000000000000000..bd888d365cc1fecb680ab6301ca49411336f203b --- /dev/null +++ b/app/models/communication/block/template/feature.rb @@ -0,0 +1,6 @@ +class Communication::Block::Template::Feature < Communication::Block::Template::Base + + has_elements + has_component :description, :rich_text + +end diff --git a/app/models/communication/block/template/feature/element.rb b/app/models/communication/block/template/feature/element.rb new file mode 100644 index 0000000000000000000000000000000000000000..25cd20876617e71004bcb3143b0ecb5568192a4b --- /dev/null +++ b/app/models/communication/block/template/feature/element.rb @@ -0,0 +1,9 @@ +class Communication::Block::Template::Feature::Element < Communication::Block::Template::Base + + has_component :title, :string + has_component :description, :text + has_component :image, :image + has_component :alt, :string + has_component :credit, :rich_text + +end diff --git a/app/models/communication/block/template/post.rb b/app/models/communication/block/template/post.rb index 617ff89ae25c1df41ee019a780ca2d128baf7ce1..de2ad77e93ac2f575e7ce5fc41f42697dfc418dc 100644 --- a/app/models/communication/block/template/post.rb +++ b/app/models/communication/block/template/post.rb @@ -1,7 +1,7 @@ class Communication::Block::Template::Post < Communication::Block::Template::Base has_elements - has_layouts [:grid, :list, :highlight] + has_layouts [:grid, :list, :highlight, :alternate] has_component :mode, :option, options: [:all, :category, :selection] has_component :posts_quantity, :number, options: 3 has_component :category_id, :category diff --git a/app/models/communication/extranet.rb b/app/models/communication/extranet.rb index 0dc31636314ab864924471003317609996665e7c..1a4615b3d6c6865f180dd318b43f9c1268235907 100644 --- a/app/models/communication/extranet.rb +++ b/app/models/communication/extranet.rb @@ -2,34 +2,35 @@ # # Table name: communication_extranets # -# id :uuid not null, primary key -# about_type :string indexed => [about_id] -# color :string -# cookies_policy :text -# css :text -# feature_alumni :boolean default(FALSE) -# feature_contacts :boolean default(FALSE) -# feature_jobs :boolean default(FALSE) -# feature_library :boolean default(FALSE) -# feature_posts :boolean default(FALSE) -# has_sso :boolean default(FALSE) -# home_sentence :text -# host :string -# name :string -# privacy_policy :text -# registration_contact :string -# sass :text -# sso_button_label :string -# sso_cert :text -# sso_mapping :jsonb -# sso_name_identifier_format :string -# sso_provider :integer default("saml") -# sso_target_url :string -# terms :text -# created_at :datetime not null -# updated_at :datetime not null -# about_id :uuid indexed => [about_type] -# university_id :uuid not null, indexed +# id :uuid not null, primary key +# about_type :string indexed => [about_id] +# allow_experiences_modification :boolean default(TRUE) +# color :string +# cookies_policy :text +# css :text +# feature_alumni :boolean default(FALSE) +# feature_contacts :boolean default(FALSE) +# feature_jobs :boolean default(FALSE) +# feature_library :boolean default(FALSE) +# feature_posts :boolean default(FALSE) +# has_sso :boolean default(FALSE) +# home_sentence :text +# host :string +# name :string +# privacy_policy :text +# registration_contact :string +# sass :text +# sso_button_label :string +# sso_cert :text +# sso_mapping :jsonb +# sso_name_identifier_format :string +# sso_provider :integer default("saml") +# sso_target_url :string +# terms :text +# created_at :datetime not null +# updated_at :datetime not null +# about_id :uuid indexed => [about_type] +# university_id :uuid not null, indexed # # Indexes # diff --git a/app/models/communication/website.rb b/app/models/communication/website.rb index a2fc9d3ccdc70669f6a7fc5b9b4d5d67aae8bf36..6e9502353145d815d8a2290548b2308f0b3e4792 100644 --- a/app/models/communication/website.rb +++ b/app/models/communication/website.rb @@ -36,7 +36,6 @@ class Communication::Website < ApplicationRecord self.filter_attributes += [:access_token] - include WithUniversity include WithAbouts include WithConfigs include WithConnectedObjects @@ -46,10 +45,12 @@ class Communication::Website < ApplicationRecord include WithImport include WithOldDependencies include WithProgramCategories + include WithReferences include WithSpecialPages include WithMenus # Menus must be created after special pages, so we can fill legal menu include WithStyle include WithTheme + include WithUniversity enum git_provider: { github: 0, @@ -78,10 +79,6 @@ class Communication::Website < ApplicationRecord ", term: "%#{sanitize_sql_like(term)}%") } - def self.save_and_sync_websites! - find_each &:save_and_sync - end - def to_s "#{name}" end diff --git a/app/models/communication/website/category.rb b/app/models/communication/website/category.rb index 612276685f122391352a1a04d20c57c8209b29fe..a05f65c5f4c9c8b5688fc56b73efc68fc32396e0 100644 --- a/app/models/communication/website/category.rb +++ b/app/models/communication/website/category.rb @@ -41,11 +41,11 @@ # fk_rails_e58348b119 (program_id => education_programs.id) # class Communication::Website::Category < ApplicationRecord + include AsDirectObject include Sanitizable include WithBlobs include WithBlocks include WithFeaturedImage - include WithGit include WithMenuItemTarget include WithPermalink include WithPosition @@ -58,8 +58,6 @@ class Communication::Website::Category < ApplicationRecord class_name: 'Communication::Website::Imported::Category', dependent: :destroy belongs_to :university - belongs_to :website, - foreign_key: :communication_website_id belongs_to :parent, class_name: 'Communication::Website::Category', optional: true diff --git a/app/models/communication/website/menu.rb b/app/models/communication/website/menu.rb index 87041f6d6966715259467fd5eca2969b75de5c24..a92deff4e91e8b6420a5c7434e31034571bf0e98 100644 --- a/app/models/communication/website/menu.rb +++ b/app/models/communication/website/menu.rb @@ -28,12 +28,11 @@ # fk_rails_dcc7198fc5 (communication_website_id => communication_websites.id) # class Communication::Website::Menu < ApplicationRecord + include AsDirectObject include Sanitizable - include WithGit include WithTranslations include WithUniversity - belongs_to :website, foreign_key: :communication_website_id has_many :items, class_name: 'Communication::Website::Menu::Item', dependent: :destroy validates :title, :identifier, presence: true diff --git a/app/models/communication/website/page.rb b/app/models/communication/website/page.rb index 2c3478afb10608c214df60cb1c15a113e2328288..09d5284361704fc7cabb834d5c396f29df538b9d 100644 --- a/app/models/communication/website/page.rb +++ b/app/models/communication/website/page.rb @@ -47,12 +47,12 @@ class Communication::Website::Page < ApplicationRecord self.ignored_columns = %w(path) include Accessible + include AsDirectObject include Sanitizable include WithBlobs include WithBlocks include WithDuplication include WithFeaturedImage - include WithGit include WithMenuItemTarget include WithPosition include WithTree @@ -65,8 +65,6 @@ class Communication::Website::Page < ApplicationRecord has_summernote :text # TODO: Remove text attribute - belongs_to :website, - foreign_key: :communication_website_id belongs_to :parent, class_name: 'Communication::Website::Page', optional: true diff --git a/app/models/communication/website/post.rb b/app/models/communication/website/post.rb index 1e19a45a1804d8fc4595028f4a7635b44f1d2fa5..1e61cbe30c244cffa5f117fcd0b299a181d38d7f 100644 --- a/app/models/communication/website/post.rb +++ b/app/models/communication/website/post.rb @@ -38,12 +38,12 @@ # fk_rails_e0eec447b0 (author_id => university_people.id) # class Communication::Website::Post < ApplicationRecord + include AsDirectObject include Sanitizable include WithBlobs include WithBlocks include WithDuplication include WithFeaturedImage - include WithGit include WithMenuItemTarget include WithPermalink include WithSlug # We override slug_unavailable? method @@ -54,10 +54,7 @@ class Communication::Website::Post < ApplicationRecord has_one :imported_post, class_name: 'Communication::Website::Imported::Post', - dependent: :destroy - belongs_to :website, - class_name: 'Communication::Website', - foreign_key: :communication_website_id + dependent: :destroy belongs_to :author, class_name: 'University::Person', optional: true diff --git a/app/models/communication/website/with_connected_objects.rb b/app/models/communication/website/with_connected_objects.rb index 8ec4a970ec1fda026714cdd6eec7ec10908059be..356752344403224d5a4ccab53b2c046c7da32624 100644 --- a/app/models/communication/website/with_connected_objects.rb +++ b/app/models/communication/website/with_connected_objects.rb @@ -2,15 +2,28 @@ module Communication::Website::WithConnectedObjects extend ActiveSupport::Concern included do - has_many :connections + has_many :connections - # before_save :clean_connections! + after_save :connect_about, if: :saved_change_to_about_id? end - def clean_connections! - start = Time.now - connect self, self - connections.reload.where('updated_at < ?', start).delete_all + # AppelĆ© + # - par un objet avec des connexions lorsqu'il est destroyed + # - par le website lui-mĆŖme au changement du about + def destroy_obsolete_connections + up_to_date_dependencies = recursive_dependencies + deletable_connection_ids = [] + connections.find_each do |connection| + has_living_connection = up_to_date_dependencies.detect { |dependency| + dependency.class.name == connection.indirect_object_type && + dependency.id == connection.indirect_object_id + } + deletable_connection_ids << connection.id unless has_living_connection + end + # On utilise delete_all pour supprimer les connexions obsolĆØtes en une unique requĆŖte DELETE FROM + # Cependant, on peut le faire car les connexions n'ont pas de callback. + # Dans le cas oĆ¹ on en rajoute au destroy, il faut repasser sur un appel de destroy sur chaque + connections.where(id: deletable_connection_ids).delete_all end def has_connected_object?(indirect_object) @@ -55,19 +68,23 @@ module Communication::Website::WithConnectedObjects University::Organization.where(id: ids) end + def is_direct_object? + true + end + + def is_indirect_object? + false + end + protected + def connect_about + self.connect(about, self) if about.present? && about.try(:is_indirect_object?) + destroy_obsolete_connections + end + def connect_object(indirect_object, direct_source, direct_source_type: nil) - # byebug if indirect_object.is_a?(Communication::Block) && indirect_object.template_kind == 'organization_chart' - return unless persisted? - # On ne connecte pas les objets inexistants - return if indirect_object.nil? - # On ne connecte pas les objets sans source - return if direct_source.nil? - # On ne connecte pas le site Ć lui-mĆŖme - return if indirect_object.is_a?(Communication::Website) - # On ne connecte pas les objets directs - return if indirect_object.respond_to?(:website) + return unless should_connect?(indirect_object, direct_source) # puts "connect #{object} (#{object.class})" direct_source_type ||= direct_source.class.base_class.to_s connection = connections.where( university: university, @@ -77,4 +94,18 @@ module Communication::Website::WithConnectedObjects .first_or_create connection.touch if connection.persisted? end + + def should_connect?(indirect_object, direct_source) + # Ce cas se produit quand on save un new website et qu'on ne passe pas un validateur + return false unless persisted? + # On ne connecte pas les objets inexistants + return false if indirect_object.nil? + # On ne connecte pas les objets sans source + return false if direct_source.nil? + # On ne connecte pas le site Ć lui-mĆŖme + return false if indirect_object.is_a?(Communication::Website) + # On ne connecte pas les objets directs (en principe Ƨa n'arrive pas) + return false if indirect_object.try(:is_direct_object?) + true + end end \ No newline at end of file diff --git a/app/models/communication/website/with_dependencies.rb b/app/models/communication/website/with_dependencies.rb deleted file mode 100644 index 2bfdc73ae855964a08be5e83ecabe8ff56ab9034..0000000000000000000000000000000000000000 --- a/app/models/communication/website/with_dependencies.rb +++ /dev/null @@ -1,16 +0,0 @@ -module Communication::Website::WithDependencies - extend ActiveSupport::Concern - - def sync_obsolete_dependencies - all_dependencies = recursive_dependencies - syncable_dependencies = recursive_dependencies(syncable_only: true) - obsolete_dependencies = all_dependencies - syncable_dependencies - return unless obsolete_dependencies.any? - obsolete_dependencies.each do |dependency| - Communication::Website::GitFile.sync self, dependency, destroy: true - end - self.git_repository.sync! - end - handle_asynchronously :sync_obsolete_dependencies, queue: :default - -end diff --git a/app/models/communication/website/with_git_repository.rb b/app/models/communication/website/with_git_repository.rb index 436b1f64ef663f438eff86b1efabc1e93b935e83..fd6bb72da7e04eff10bb34809e1ea6641653680c 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 + + # Supprimer tous les git_files qui ne sont pas dans les recursive_dependencie_syncable + def destroy_obsolete_git_files + website_git_files.find_each do |git_file| + dependency = git_file.about + is_obsolete = !dependency.in?(recursive_dependencie_syncable) + if is_obsolete + # TODO git_file.destroy serait plus ActiveRecord + Communication::Website::GitFile.sync(self, dependency, destroy: true) + end + end + self.git_repository.sync! + end + handle_asynchronously :destroy_obsolete_git_files, queue: :default end diff --git a/app/models/communication/website/with_old_dependencies.rb b/app/models/communication/website/with_old_dependencies.rb index 527d1aa980f3cd3718a99d0ef08aa0a9fabf840b..39e51edead9c61358aaca5b360d192c03db2c50c 100644 --- a/app/models/communication/website/with_old_dependencies.rb +++ b/app/models/communication/website/with_old_dependencies.rb @@ -41,15 +41,15 @@ module Communication::Website::WithOldDependencies end def administrators - about&.administrators + has_administrators? ? about.administrators : University::Person.none end def researchers - about&.researchers + has_researchers? ? about.researchers : University::Person.none end def teachers - about&.teachers + has_teachers? ? about.teachers : University::Person.none end def people_in_blocks diff --git a/app/models/concerns/as_direct_object.rb b/app/models/concerns/as_direct_object.rb new file mode 100644 index 0000000000000000000000000000000000000000..cfbaec991499b42af9995809793584b67ba5f761 --- /dev/null +++ b/app/models/concerns/as_direct_object.rb @@ -0,0 +1,34 @@ +# Ce concern ajoute les Ć©lĆ©ments nĆ©cessaires pour les objets directs : +# - DĆ©pendances (avec et via synchro) +# - Git +# - GitFiles +# - RĆ©fĆ©rences +# - Connexions (en tant que source) +module AsDirectObject + extend ActiveSupport::Concern + + included do + include WithDependencies + include WithGit + include WithGitFiles + include WithReferences + + belongs_to :website, + class_name: 'Communication::Website', + foreign_key: :communication_website_id + + has_many :connections, + as: :direct_source, + class_name: 'Communication::Website::Connection', + dependent: :destroy # When the direct object disappears all connections with the object as a source must disappear + + end + + def is_direct_object? + true + end + + def is_indirect_object? + false + end +end \ No newline at end of file diff --git a/app/models/concerns/as_indirect_object.rb b/app/models/concerns/as_indirect_object.rb new file mode 100644 index 0000000000000000000000000000000000000000..118bbe5ce4f0ba34bfc55ac67ddb0dc8fd72fa0e --- /dev/null +++ b/app/models/concerns/as_indirect_object.rb @@ -0,0 +1,89 @@ +# Ce concern ajoute les Ć©lĆ©ments nĆ©cessaires pour les objets indirects : +# - connexions +# - dĆ©pendances (avec et via synchro) +# - rĆ©fĆ©rences nĆ©cessaires +module AsIndirectObject + extend ActiveSupport::Concern + + included do + # Les blocs sont des objets indirects, mais n'ont pas de GitFiles, on n'inclut donc pas WithGitFiles ici + include WithDependencies + include WithReferences + + has_many :connections, + as: :indirect_object, + class_name: 'Communication::Website::Connection' + # Pas dependent_destroy parce que le processus est plus sophistiquĆ©, et est fait dans la mĆ©thode destroy + has_many :websites, + through: :connections + # Ce serait super de faire la ligne ci-dessous, mais Rails ne sait pas faire Ƨa avec un objet polymorphe (direct_source) + # has_many :direct_sources, through: :connections + + after_save :sync_connections + after_touch :sync_connections + end + + def is_direct_object? + false + end + + def is_indirect_object? + true + end + + def for_website?(website) + website.has_connected_object?(self) + end + + def direct_sources + @direct_sources ||= begin + # On initialise les direct_sources avec les connexions existantes + direct_sources = direct_sources_from_existing_connections + # On boucle sur les rĆ©fĆ©rences pour rĆ©cupĆ©rer les direct sources manquantes + references.each do |reference| + direct_sources += direct_sources_from_reference(reference) + end + direct_sources.uniq + end + end + + def destroy + # On est obligĆ©s d'overwrite la mĆ©thode destroy pour Ć©viter un problĆØme d'Å“uf et de poule. + # On a besoin que les websites puissent recalculer leurs recursive_dependencies + # et on a besoin que ces recursive_dependencies n'incluent pas l'objet courant, puisqu'il est "en cours de destruction" (ni ses propres recursive_dependencies). + # Mais si on dĆ©truit juste l'objet et qu'on fait un `after_destroy :clean_website_connections` + # on ne peut plus accĆ©der aux websites (puisque l'objet est dĆ©jĆ dĆ©truit et ses connexions en cascades). + # Donc : + # 1. on stocke les websites + # 2. PUIS on dĆ©truit les connexions + # 3. PUIS on dĆ©truit l'objet (la mĆ©thode destroy normale) + # 4. PUIS on demande aux websites stockĆ©s de nettoyer leurs connexions + self.transaction do + website_ids = websites.pluck(:id) + connections.destroy_all + super + Communication::Website.where(id: website_ids).each do |website| + website.destroy_obsolete_connections + website.save_and_sync + end + end + end + + protected + + def direct_sources_from_existing_connections + connections.collect &:direct_source + end + + def direct_sources_from_reference(reference) + reference.is_direct_object? ? [reference] # RĆ©cupĆ©ration de la connexion directe + : reference.direct_sources # RĆ©cursivitĆ© sur les rĆ©fĆ©rences + end + + def sync_connections + direct_sources.each do |direct_source| + direct_source.website.connect self, direct_source + direct_source.sync_with_git + end + end +end \ No newline at end of file diff --git a/app/models/concerns/with_abouts.rb b/app/models/concerns/with_abouts.rb index c2cbb413bccc9d353fd07b1a34b56549a97cf7ec..4be1b380992c26208b575eab97037a611fd5fb15 100644 --- a/app/models/concerns/with_abouts.rb +++ b/app/models/concerns/with_abouts.rb @@ -6,6 +6,8 @@ module WithAbouts polymorphic: true, optional: true + before_validation :nullify_about_id_if_about_type_changed_to_blank + scope :for_about_type, -> (type) { where(about_type: type) } def self.about_types @@ -17,6 +19,11 @@ module WithAbouts Research::Journal.name, ] end + end + + protected + def nullify_about_id_if_about_type_changed_to_blank + self.about_id = nil if about_type_changed? && about_type.blank? end end diff --git a/app/models/concerns/with_connections.rb b/app/models/concerns/with_connections.rb deleted file mode 100644 index 16f4b84d26c5c5c27450c7375221553a06246411..0000000000000000000000000000000000000000 --- a/app/models/concerns/with_connections.rb +++ /dev/null @@ -1,71 +0,0 @@ -# Concern exclusivement utilisĆ© pour les objets indirects -module WithConnections - extend ActiveSupport::Concern - - included do - include WithDependencies - include WithReferences - - has_many :connections, - as: :indirect_object, - class_name: 'Communication::Website::Connection', - dependent: :destroy # When the indirect object disappears, the connections must disappear - has_many :websites, - through: :connections - # Ce serait super de faire la ligne ci-dessous, mais Rails ne sait pas faire Ƨa avec un objet polymorphe (direct_source) - # has_many :direct_sources, through: :connections - - after_save :sync_connections - after_touch :sync_connections - after_save :sync_obsolete_dependencies - after_destroy :destroy_obsolete_connections - end - - def for_website?(website) - website.has_connected_object?(self) - end - - def direct_sources - @direct_sources ||= begin - # On initialise les direct_sources avec les connexions existantes - direct_sources = direct_sources_from_existing_connections - # On boucle sur les rĆ©fĆ©rences pour rĆ©cupĆ©rer les direct sources manquantes - references.each do |reference| - direct_sources += direct_sources_from_reference(reference) - end - direct_sources.uniq - end - end - - protected - - def direct_sources_from_existing_connections - connections.collect &:direct_source - end - - def direct_sources_from_reference(reference) - reference.respond_to?(:website) ? [reference] # RĆ©cupĆ©ration de la connexion directe - : reference.direct_sources # RĆ©cursivitĆ© sur les rĆ©fĆ©rences - end - - def sync_connections - direct_sources.each do |direct_source| - direct_source.website.connect self, direct_source - direct_source.save_and_sync - end - end - - # La suppression d'un objet indirect dĆ©clenche le recalcul des connexions de tous les objets directs - def destroy_obsolete_connections - direct_sources.each do |direct_source| - # TODO - end - end - - def sync_obsolete_dependencies - # TODO: pas ouf de passer par le site, ce serait plus lĆ©ger en calcul de faire une analyse plus Ć©troite - websites.each do |website| - website.sync_obsolete_dependencies - end - end -end \ No newline at end of file diff --git a/app/models/concerns/with_dependencies.rb b/app/models/concerns/with_dependencies.rb index dbc5ca0d8bf0a940192d0ca09aca538614bcd845..5b8526ead1a1afcb9c2920b6bb7add7cdce2320d 100644 --- a/app/models/concerns/with_dependencies.rb +++ b/app/models/concerns/with_dependencies.rb @@ -5,6 +5,17 @@ module WithDependencies extend ActiveSupport::Concern + included do + attr_accessor :previous_dependencies + + if self < ActiveRecord::Base + before_save :snapshot_dependencies + after_save :clean_websites_if_necessary + after_destroy :clean_websites + end + end + + # Cette mĆ©thode doit ĆŖtre dĆ©finie dans chaque objet, # et renvoyer un tableau de ses rĆ©fĆ©rences directes. # Jamais de rĆ©fĆ©rence indirecte ! @@ -24,14 +35,71 @@ module WithDependencies end end + # On ne liste pas les objets en cours de suppression + # return array if respond_to?(:mark_for_destruction?) && mark_for_destruction + # On renvoie l'array tel quel, non modifiĆ©, si on demande les contenus syncable_only et que le contenu ne l'est pas def recursive_dependencies(array: [], syncable_only: false) - return array if syncable_only && !syncable? + return array unless dependency_should_be_synced?(self, syncable_only) dependencies.each do |dependency| - next if dependency.in?(array) + # Si l'objet ne doit pas ĆŖtre ajoutĆ© on n'ajoute pas non plus ses dĆ©pendances rĆ©cursives + # C'est le fait de couper ici qui Ć©vite la boucle infinie + next unless dependency_should_be_added?(array, dependency, syncable_only) array << dependency next unless dependency.respond_to?(:recursive_dependencies) array = dependency.recursive_dependencies(array: array, syncable_only: syncable_only) end array.compact end + + def recursive_dependencies_syncable + @recursive_dependencies_syncable ||= recursive_dependencies(syncable_only: true) + end + + protected + + # Si l'objet est dĆ©jĆ lĆ , on ne doit pas l'ajouter + # Si l'objet n'est pas syncable, on ne doit pas l'ajouter non plus + def dependency_should_be_added?(array, dependency, syncable_only) + !dependency.in?(array) && dependency_should_be_synced?(dependency, syncable_only) + end + + # Si on n'est pas en syncable only on liste tout, sinon, il faut analyser + def dependency_should_be_synced?(dependency, syncable_only) + !syncable_only || (dependency.respond_to?(:syncable?) && dependency.syncable?) + end + + # Stockage en RAM des dĆ©pendances avant enregistrement + def snapshot_dependencies + @previous_dependencies = persisted? ? reloaded_recursive_dependencies_syncable_filtered : [] + end + + def clean_websites_if_necessary + # Debug :) + # puts self + # puts " previous_dependencies #{ @previous_dependencies }" + # puts " recursive_dependencies_syncable #{ reloaded_recursive_dependencies_syncable_filtered }" + # puts " missing_dependencies_after_save #{ missing_dependencies_after_save }" + # puts + clean_websites if missing_dependencies_after_save.any? + end + + def clean_websites + return unless respond_to?(:is_direct_object?) + + if is_direct_object? + website.destroy_obsolete_git_files + elsif is_indirect_object? + websites.each(&:destroy_obsolete_git_files) + end + end + + def missing_dependencies_after_save + @previous_dependencies - reloaded_recursive_dependencies_syncable_filtered + end + + def reloaded_recursive_dependencies_syncable_filtered + reloaded_object = self.class.unscoped.find(id) + reloaded_dependencies = reloaded_object.recursive_dependencies_syncable + DependenciesFilter.filtered(reloaded_dependencies) + end end \ No newline at end of file diff --git a/app/models/concerns/with_git.rb b/app/models/concerns/with_git.rb index af457c0e184ca094de6085b9e375b106f26f59ad..b06c6f5bfc98be17ce46842cd962cc845786b4aa 100644 --- a/app/models/concerns/with_git.rb +++ b/app/models/concerns/with_git.rb @@ -1,13 +1,6 @@ module WithGit extend ActiveSupport::Concern - included do - # WithGit a besoin de ces 3 concerns - include WithDependencies - include WithGitFiles - include WithReferences - end - def save_and_sync if save sync_with_git @@ -49,11 +42,6 @@ module WithGit def destroy_from_git return unless website.git_repository.valid? Communication::Website::GitFile.sync website, self, destroy: true - # # FIXME - # dependencies = git_destroy_dependencies(website).to_a.flatten.uniq.compact - # dependencies.each do |object| - # Communication::Website::GitFile.sync website, object, destroy: true - # end website.git_repository.sync! end diff --git a/app/models/concerns/with_translations.rb b/app/models/concerns/with_translations.rb index 3d1771af782eeccbbe4ecb55004e9a3f356eef04..50d90c41243c6b321629814a5021c3c45a935fdb 100644 --- a/app/models/concerns/with_translations.rb +++ b/app/models/concerns/with_translations.rb @@ -16,7 +16,7 @@ module WithTranslations def available_languages @available_languages ||= begin - languages = respond_to?(:website) ? website.languages : Language.all + languages = is_direct_object? ? website.languages : Language.all languages.ordered end end diff --git a/app/models/education/diploma.rb b/app/models/education/diploma.rb index ef19ef4a6bf45f4a18bcd66b70884540d0c7bb10..0d31049aadc1a51f4da44ce1d3739b908a7f23e1 100644 --- a/app/models/education/diploma.rb +++ b/app/models/education/diploma.rb @@ -23,9 +23,9 @@ # fk_rails_6cb2e9fa90 (university_id => universities.id) # class Education::Diploma < ApplicationRecord + include AsIndirectObject include Sanitizable include WithBlocks - include WithConnections include WithGitFiles include WithPermalink include WithSlug diff --git a/app/models/education/program.rb b/app/models/education/program.rb index 510b58acb70f29d7fe1db5c375ad7fe3acd4fd31..76f86dface99c1a7414f5c73f38a0c325eb85ae2 100644 --- a/app/models/education/program.rb +++ b/app/models/education/program.rb @@ -51,11 +51,11 @@ # class Education::Program < ApplicationRecord include Aboutable + include AsIndirectObject include Sanitizable include WithAlumni include WithBlobs include WithBlocks - include WithConnections include WithDiploma include WithFeaturedImage include WithGitFiles diff --git a/app/models/education/school.rb b/app/models/education/school.rb index efd65404f37fb25bc48a6b5687e107afb86ad4ba..b2160c3e240b44420c52ac7df63c1bf8b564ca4f 100644 --- a/app/models/education/school.rb +++ b/app/models/education/school.rb @@ -26,10 +26,10 @@ # class Education::School < ApplicationRecord include Aboutable + include AsIndirectObject include Sanitizable include WithAlumni include WithBlobs - include WithConnections include WithCountry include WithGitFiles include WithPrograms # must come before WithAlumni and WithTeam diff --git a/app/models/research/hal/publication.rb b/app/models/research/hal/publication.rb index 45103be805f600af7d896b8fdbcc7ae53ac9a286..9682b57fb4da7b323272410c52ad7705777e7a09 100644 --- a/app/models/research/hal/publication.rb +++ b/app/models/research/hal/publication.rb @@ -20,8 +20,8 @@ # index_research_hal_publications_on_docid (docid) # class Research::Hal::Publication < ApplicationRecord + include AsIndirectObject include Sanitizable - include WithConnections include WithGitFiles include WithSlug diff --git a/app/models/research/journal.rb b/app/models/research/journal.rb index afbc32ba9c48f572031649d8b7213cc84a3e7039..a97d40b27bf47b01f7f620b0574973f620f2d3b6 100644 --- a/app/models/research/journal.rb +++ b/app/models/research/journal.rb @@ -20,9 +20,9 @@ # fk_rails_96097d5f10 (university_id => universities.id) # class Research::Journal < ApplicationRecord - include Sanitizable + include AsIndirectObject include Aboutable - include WithConnections + include Sanitizable include WithGitFiles include WithUniversity diff --git a/app/models/research/journal/paper.rb b/app/models/research/journal/paper.rb index dcf9299c8b272916f1762b0181542e29b92ec876..3ed767691c00946415f4d432602acc34f79551a4 100644 --- a/app/models/research/journal/paper.rb +++ b/app/models/research/journal/paper.rb @@ -43,10 +43,10 @@ # fk_rails_db4e38788c (kind_id => research_journal_paper_kinds.id) # class Research::Journal::Paper < ApplicationRecord + include AsIndirectObject include Sanitizable include WithBlobs include WithBlocks - include WithConnections include WithGitFiles include WithPermalink include WithPosition diff --git a/app/models/research/journal/paper/kind.rb b/app/models/research/journal/paper/kind.rb index 85ab5934fc8b2ec2b94d39d79f6c00cfd7cc35f4..8b376f5154b7333c32faed94c8fc870d597036c3 100644 --- a/app/models/research/journal/paper/kind.rb +++ b/app/models/research/journal/paper/kind.rb @@ -21,8 +21,8 @@ # fk_rails_8e6f992b9d (university_id => universities.id) # class Research::Journal::Paper::Kind < ApplicationRecord + include AsIndirectObject include Sanitizable - include WithConnections include WithGitFiles include WithSlug include WithUniversity diff --git a/app/models/research/journal/volume.rb b/app/models/research/journal/volume.rb index f7f72b6850da4314ab10de778744ff0f927aeb8b..513f44046ef6d22fe10c4631d66471c3794f80d7 100644 --- a/app/models/research/journal/volume.rb +++ b/app/models/research/journal/volume.rb @@ -30,9 +30,9 @@ # fk_rails_c83d5e9068 (university_id => universities.id) # class Research::Journal::Volume < ApplicationRecord + include AsIndirectObject include Sanitizable include WithBlobs - include WithConnections include WithFeaturedImage include WithGitFiles include WithPermalink diff --git a/app/models/research/laboratory.rb b/app/models/research/laboratory.rb index 866a143237e48b4ef025a140a7202479e5d9ce9d..eb0f676f3480a88e58e20ef30b13eebdbc1be410 100644 --- a/app/models/research/laboratory.rb +++ b/app/models/research/laboratory.rb @@ -22,8 +22,8 @@ # class Research::Laboratory < ApplicationRecord include Aboutable + include AsIndirectObject include Sanitizable - include WithConnections include WithCountry include WithGitFiles diff --git a/app/models/university/organization.rb b/app/models/university/organization.rb index fd9f77990ea7138fb6fc104790fb9f2d9735d787..c5302c089af886b379cbd402c50a68fd940ea459 100644 --- a/app/models/university/organization.rb +++ b/app/models/university/organization.rb @@ -40,10 +40,10 @@ # fk_rails_35fcd198e0 (university_id => universities.id) # class University::Organization < ApplicationRecord + include AsIndirectObject include Sanitizable include WithBlobs include WithBlocks - include WithConnections include WithCountry include WithGeolocation include WithGitFiles diff --git a/app/models/university/person.rb b/app/models/university/person.rb index 1f60a92fbc577e9af35c6a737f0344f209b4adaf..fa91f6d149b2a87287e555d0c4dbb3b193ba5daa 100644 --- a/app/models/university/person.rb +++ b/app/models/university/person.rb @@ -53,10 +53,10 @@ # fk_rails_da35e70d61 (university_id => universities.id) # class University::Person < ApplicationRecord + include AsIndirectObject include Sanitizable include WithBlobs include WithBlocks - include WithConnections include WithCountry include WithEducation include WithExperiences diff --git a/app/services/dependencies_filter.rb b/app/services/dependencies_filter.rb new file mode 100644 index 0000000000000000000000000000000000000000..4523403c22c3860252e2cae806079d5bd0646fc0 --- /dev/null +++ b/app/services/dependencies_filter.rb @@ -0,0 +1,12 @@ +class DependenciesFilter + + # [ + # "gid://osuny/Communication::Block/4ac9f6fe-80cd-46f6-becc-fc14b3fecea0", + # "gid://osuny/University::Person/36501bf0-99b9-58f9-b269-bf161b451c43" + # ] + def self.filtered(dependencies) + dependencies.select { |dependency| dependency.is_a?(ActiveRecord::Base) } + .map { |dependency| dependency.to_global_id.to_s } + .uniq + end +end \ No newline at end of file diff --git a/app/services/osuny/simple_navigation_renderer.rb b/app/services/osuny/simple_navigation_renderer.rb index b6857b68e21279677696b68b500714ad00d18d76..b1dcd9275ac3f0fdfcef8fad3ed1c1a3092b0e34 100644 --- a/app/services/osuny/simple_navigation_renderer.rb +++ b/app/services/osuny/simple_navigation_renderer.rb @@ -1,5 +1,5 @@ class Osuny::SimpleNavigationRenderer < SimpleNavigation::Renderer::Base - OPEN = "<div class=\"col-md-4 col-lg-3 mb-5\">" + OPEN = "<div class=\"col-sm-6 col-md-4 col-lg-3 mb-5\">" CLOSE = "</div>" attr_accessor :content, :index, :item diff --git a/app/views/admin/application/i18n/_widget.html.erb b/app/views/admin/application/i18n/_widget.html.erb index a761a658dfbcbf13dcda6d2d9ec3da966564edb4..dd235bf33dbc7a7869ba3d916d1b049b0641f4a4 100644 --- a/app/views/admin/application/i18n/_widget.html.erb +++ b/app/views/admin/application/i18n/_widget.html.erb @@ -1,7 +1,7 @@ <% if about.available_languages.many? %> <% - route_args = about.respond_to?(:website) ? [:admin, about.becomes(about.class.base_class)] - : [:show_in_language, :admin, about.becomes(about.class.base_class)] + route_args = about.is_direct_object? ? [:admin, about.becomes(about.class.base_class)] + : [:show_in_language, :admin, about.becomes(about.class.base_class)] %> <%= osuny_panel t('internationalization.label') do %> <ol class="list-unstyled"> diff --git a/app/views/admin/communication/blocks/_preview.html.erb b/app/views/admin/communication/blocks/_preview.html.erb index bd26dfe7acf4a9579b6cae270b2b5c53423d96b8..1fc6d39b60eb598b4f0d980d138013af92860f17 100644 --- a/app/views/admin/communication/blocks/_preview.html.erb +++ b/app/views/admin/communication/blocks/_preview.html.erb @@ -1,18 +1,4 @@ -<% is_leaflet_needed = true; %> - <% about.blocks.published.ordered.each do |block| %> <% @block = block %> <%= render "admin/communication/blocks/templates/#{@block.template_kind}/preview" %> - <% if block.template_kind == "partners" && block.data[:layout] == "map" %> - <% is_leaflet_needed = true; %> - <% end %> -<% end %> - -<% if is_leaflet_needed %> - <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.3/dist/leaflet.css" - integrity="sha256-kLaT2GOSpHechhsozzB+flnD+zUyjE2LlfWPgU04xyI=" - crossorigin=""/> - <script src="https://unpkg.com/leaflet@1.9.3/dist/leaflet.js" - integrity="sha256-WBkoXOwTeyKclOHuWtc+i2uENFpDZ9YPdf5Hf+D7ewM=" - crossorigin=""></script> <% end %> diff --git a/app/views/admin/communication/blocks/templates/features/_edit.html.erb b/app/views/admin/communication/blocks/templates/features/_edit.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..e9a60f1c569c753464c16a159eeab64dd613273f --- /dev/null +++ b/app/views/admin/communication/blocks/templates/features/_edit.html.erb @@ -0,0 +1,35 @@ +<div class="row pure__row--small"> + <div class="col-xl-6"> + <%= block_component_edit :description %> + </div> +</div> + +<%= block_component_add_element t('.add_element') %> +<draggable :list="data.elements" handle=".dragHandle" class="mb-3 <%= if_appstack 'list-group' %>"> + <div v-for="(element, index) in data.elements" class="draggable-item <%= if_appstack 'list-group-item' %>"> + <div> + <a class="btn ps-0 pt-0 dragHandle"><i class="<%= Icon::DRAG %> handle"></i></a>{{element.title}} + <a class="btn btn-sm text-danger float-end pe-0" + v-on:click="data.elements.splice(data.elements.indexOf(element), 1)" + title="<%= t '.remove_element' %>"> + <i class="<%= Icon::DELETE %>"></i> + </a> + </div> + <div class="row pure__row--small"> + <div class="col-lg-4"> + <%= block_component_edit :title, template: @element %> + <%= block_component_edit :description, template: @element, rows: 5 %> + </div> + <div class="col-lg-4"> + <%= block_component_edit :image, template: @element %> + </div> + <div class="col-lg-4" v-show="element.image.id != ''"> + <%= block_component_edit :alt, template: @element %> + <%= block_component_edit :credit, template: @element %> + </div> + </div> + </div> +</draggable> +<div v-show="data.elements.length > 2"> + <%= block_component_add_element t('.add_element') %> +</div> \ No newline at end of file diff --git a/app/views/admin/communication/blocks/templates/features/_preview.html.erb b/app/views/admin/communication/blocks/templates/features/_preview.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/app/views/admin/communication/blocks/templates/features/_static.html.erb b/app/views/admin/communication/blocks/templates/features/_static.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..2dd180eae5b5d1367c84827e7f24a8b8f89d7ea0 --- /dev/null +++ b/app/views/admin/communication/blocks/templates/features/_static.html.erb @@ -0,0 +1,9 @@ +<%= block_component_static :description %> + elements: +<% block.template.elements.each do |element| %> +<%= block_component_static :title, template: element, list: true, depth: 4 %> +<%= block_component_static :description, template: element, depth: 5 %> +<%= block_component_static :image, template: element, depth: 5 %> +<%= block_component_static :alt, template: element, depth: 5 %> +<%= block_component_static :credit, template: element, depth: 5 %> +<% end %> diff --git a/app/views/admin/communication/blocks/templates/pages/_preview.html.erb b/app/views/admin/communication/blocks/templates/pages/_preview.html.erb index 42f0873509ba6bec96c72a782d8ebf2352379e5e..36bf97d8769a3bc319ac57580dc8cb27b15e23fc 100644 --- a/app/views/admin/communication/blocks/templates/pages/_preview.html.erb +++ b/app/views/admin/communication/blocks/templates/pages/_preview.html.erb @@ -5,49 +5,90 @@ unless @block.title.blank? end class_name += " block-pages--" + @block.template.layout %> -<section class="<%= class_name %>" style="display: none;"> +<section class="<%= class_name %>"> <div class="container"> <div class="block-content"> - <% if @block.data %> - <% if @block.template.page %> - <%#= @block.template.page.slug %> - <% end %> + <% unless @block.title.blank? %> + <div class="top"> + <% unless @block.title.blank? %> - <% if @block.template.show_main_description %> - <p></p> + <% if @block.template.layout === "cards" || @block.template.layout === "list" %> + <h2><%= link_to @block.template.page, @block.template.page.url %></h2> + + <% elsif @block.template.layout === "grid" && @block.template.page && @block.template.show_main_description %> + <h2><%= link_to @block.title, @block.template.page.url %></h2> + <p class="description"><%= @block.template.page.summary %></p> + + <% else %> + <h2><%= @block.title %></h2> + <% end %> + + <% end %> + <% if @block.template.layout === "cards" && @block.template.show_main_description && @block.data %> + <div class="description"> + <p><%= @block.template.page.summary %></p> + </div> + <% end %> + </div> + <% if @block.template.layout === "list" && @block.template.show_main_description && @block.data %> + <p class="description"><%= @block.template.page.summary %></p> <% end %> + <% end %> + <% if @block.data %> <% if @block.template.layout === "list" %> - <ul> - <% @block.template.elements.each do |element| %> - <li> - <%#= element %> - </li> + <% @block.template.selected_pages.each do |page| + next if page.nil? + %> + <li><%= link_to page, page.url %></li> <% end %> </ul> <% elsif @block.template.layout === "cards" %> - <div class="cards"> - <% @block.template.elements.each do |element| %> + <% @block.template.selected_pages.each do |page| + next if page.nil? + %> <article class="card"> - <%# <%= element %> + <h3> + <%= link_to page, page.url %> + </h3> <% if @block.template.show_description %> - <p><%#= element.summary %></p> + <p><%= page.summary %></p> + <% end %> + + <p class="more meta" aria-hidden="true"><%= t 'admin.communication.blocks.templates.pages.layouts.cards.more' %></p> + + <% if @block.template.show_image %> + <div class="media" itemprop="image"> + <% if page.featured_image.attached? %> + <%= kamifusen_tag page.featured_image %> + <% end %> + </div> <% end %> </article> <% end %> </div> <% else %> - <div class="grid"> - <% @block.template.elements.each do |element| %> + <% @block.template.selected_pages.each do |page| + next if page.nil? + %> <article> - <%# <%= element %> + <h3> + <%= link_to page, page.url %> + </h3> <% if @block.template.show_description %> - <p><%#= element.summary %></p> + <p><%= page.summary %></p> + <% end %> + <% if @block.template.show_image %> + <div class="media" itemprop="image"> + <% if page.featured_image.attached? %> + <%= kamifusen_tag page.featured_image %> + <% end %> + </div> <% end %> </article> <% end %> diff --git a/app/views/admin/communication/blocks/templates/partners/_preview.html.erb b/app/views/admin/communication/blocks/templates/partners/_preview.html.erb index 3d14a837cd01c07bf62f7a736c28b8a6926d2b7a..40246eb957ea8eb7e8cf8f241bc7a295e63eeefd 100644 --- a/app/views/admin/communication/blocks/templates/partners/_preview.html.erb +++ b/app/views/admin/communication/blocks/templates/partners/_preview.html.erb @@ -24,44 +24,37 @@ <% if @block.template.layout == "grid" %> <div class="organizations grid"> - <% @block.template.elements.each do |element| %> - <article class="organization"> - <h3> - <% if element.best_url %> - <a href="<%= element.best_url %>" target="_blank"> - <% end %> - <%= element.best_name %> - <% if element.best_url%> - </a> - <% end %> - </h3> - <div class="media"> - <%= kamifusen_tag element.best_logo, width: 600%> - </div> - </article> - <% end %> - </div> - <% else %> + <% else # Map %> <div class="map" data-marker-icon="<%= image_path 'map-marker.svg' %>"> - <% @block.template.elements.each do |element| %> - <article class="organization" data-latitude="<%= element.organization.latitude %>" data-longitude="<%= element.organization.longitude %>"> - <h3> - <% if element.best_url %> - <a href="<%= element.best_url %>" target="_blank"> - <% end %> - <%= element.best_name %> - <% if element.best_url%> - </a> - <% end %> - </h3> + <link rel="stylesheet" + href="https://unpkg.com/leaflet@1.9.3/dist/leaflet.css" + integrity="sha256-kLaT2GOSpHechhsozzB+flnD+zUyjE2LlfWPgU04xyI=" + crossorigin=""/> + <script src="https://unpkg.com/leaflet@1.9.3/dist/leaflet.js" + integrity="sha256-WBkoXOwTeyKclOHuWtc+i2uENFpDZ9YPdf5Hf+D7ewM=" + crossorigin=""></script> + <% end %> + <% @block.template.elements.each do |element| %> + <article class="organization" + data-latitude="<%= element.organization&.latitude %>" + data-longitude="<%= element.organization&.longitude %>"> + <h3> + <% if element.best_url %> + <a href="<%= element.best_url %>" target="_blank"> + <% end %> + <%= element.best_name %> + <% if element.best_url%> + </a> + <% end %> + </h3> + <% if element.best_logo %> <div class="media"> <%= kamifusen_tag element.best_logo, width: 600%> </div> - </article> - <% end %> - </div> - <% end %> + <% end %> + </article> + <% end %> + </div> </div> </div> </section> - diff --git a/app/views/admin/communication/blocks/templates/posts/_preview.html.erb b/app/views/admin/communication/blocks/templates/posts/_preview.html.erb index 0d73386078540ecaa076a29d2db3ed8cbbeb7d8f..3e1fa9f7d19e174fb56c77821c69e5b914e47204 100644 --- a/app/views/admin/communication/blocks/templates/posts/_preview.html.erb +++ b/app/views/admin/communication/blocks/templates/posts/_preview.html.erb @@ -1,11 +1,13 @@ <% -$class = "block block-posts" +class_name = "block block-posts" unless @block.title.blank? - $class += " block-with-title" + class_name += " block-with-title" end -$class += " block-posts--" + @block.template.layout +class_name += " block-posts--" + @block.template.layout + +date_format = "%e %B %Y" %> -<section class="<%= $class %>"> +<section class="<%= class_name %>"> <div class="container"> <div class="block-content"> <% unless @block.title.blank? %> @@ -13,26 +15,148 @@ $class += " block-posts--" + @block.template.layout <h2><%= @block.title %></h2> </div> <% end %> - <div class="list"> - <% if @block.data %> - <% @block.template.selected_posts.each do |post| %> - <article class="post" itemprop="blogPosts" itemscope itemtype="http://schema.org/BlogPosting"> - <div class="post-content"> - <a href="#"><%= post %></a> - <p itemprop="articleBody"><%= post.summary %></p> - </div> - <div class="post-meta"> - <time itemprop="datePublished" datetime="<%= post.published_at %>"><%= post.published_at.to_date %></time> - </div> - <% if post.best_featured_image.attached? %> + + <% if @block.template.layout === "list" %> + <div class="list"> + <% if @block.data %> + <% @block.template.selected_posts.each do |post| %> + <article class="post" itemprop="blogPosts" itemscope itemtype="http://schema.org/BlogPosting"> + <div class="post-content"> + <h3 itemprop="headline"> + <%= link_to post, post.url %> + </h3> + <% if !post.categories.empty? %> + <ul class="post-categories"> + <% post.categories.each do |category| %> + <%= link_to category, category.path %> + <% end %> + </ul> + <% end %> + <p itemprop="articleBody"><%= post.summary %></p> + <div class="post-meta"> + <time itemprop="datePublished" datetime="<%= post.published_at %>"><%= l(post.published_at, format: date_format) %></time> + <% if post.author.present? %> + <div class="post-author" itemscope itemtype="https://schema.org/Person" itemprop="author"> + <p itemprop="name"><%= post.author %></p> + </div> + <% end %> + </div> + </div> <div class="media"> - <%= kamifusen_tag post.best_featured_image %> + <% if post.best_featured_image.attached? %> + <%= kamifusen_tag post.best_featured_image %> + <% end %> </div> - <% end %> - </article> + </article> + <% end %> <% end %> + </div> + + <% elsif @block.template.layout === "highlight"%> + <% if @block.data + $highlight_post = @block.template.selected_posts.first + %> + <div class="highlight"> + <div class="highlight-post"> + <article class="post" itemprop="blogPosts" itemscope itemtype="http://schema.org/BlogPosting"> + <div class="post-content"> + <h3 itemprop="headline"> + <%= link_to $highlight_post, $highlight_post.url %> + </h3> + <% if !$highlight_post.categories.empty? %> + <ul class="post-categories"> + <% $highlight_post.categories.each do |category| %> + <%= link_to category, category.path %> + <% end %> + </ul> + <% end %> + <p itemprop="articleBody"><%= $highlight_post.summary %></p> + <div class="post-meta"> + <time itemprop="datePublished" datetime="<%= $highlight_post.published_at %>"><%= l($highlight_post.published_at, format: date_format) %></time> + <% if $highlight_post.author.present? %> + <div class="post-author" itemscope itemtype="https://schema.org/Person" itemprop="author"> + <p itemprop="name"><%= $highlight_post.author %></p> + </div> + <% end %> + </div> + </div> + <div class="media"> + <% if $highlight_post.best_featured_image.attached? %> + <%= kamifusen_tag $highlight_post.best_featured_image %> + <% end %> + </div> + </article> + </div> + + <div class="list"> + <% @block.template.selected_posts.each do |post| + next if post.nil? + %> + <article class="post" itemprop="blogPosts" itemscope itemtype="http://schema.org/BlogPosting"> + <div class="post-content"> + <h3 itemprop="headline"> + <%= link_to post, post.url %> + </h3> + <% if !post.categories.empty? %> + <ul class="post-categories"> + <% post.categories.each do |category| %> + <%= link_to category, category.path %> + <% end %> + </ul> + <% end %> + <p itemprop="articleBody"><%= post.summary %></p> + <div class="post-meta"> + <time itemprop="datePublished" datetime="<%= post.published_at %>"><%= l(post.published_at, format: date_format) %></time> + <% if post.author.present? %> + <div class="post-author" itemscope itemtype="https://schema.org/Person" itemprop="author"> + <p itemprop="name"><%= post.author %></p> + </div> + <% end %> + </div> + </div> + </article> + <% end %> + </div> + </div> <% end %> - </div> + <% else %> + <div class="grid"> + <% if @block.data %> + <% @block.template.selected_posts.each do |post| + next if post.nil? + %> + <article class="post" itemprop="blogPosts" itemscope itemtype="http://schema.org/BlogPosting"> + <div class="post-content"> + <h3 itemprop="headline"> + <%= link_to post, post.url %> + </h3> + <% if !post.categories.empty? %> + <ul class="post-categories"> + <% post.categories.each do |category| %> + <%= link_to category, category.path %> + <% end %> + </ul> + <% end %> + <p itemprop="articleBody"><%= post.summary %></p> + <div class="post-meta"> + <time itemprop="datePublished" datetime="<%= post.published_at %>"><%= l(post.published_at, format: date_format) %></time> + <% if post.author.present? %> + <div class="post-author" itemscope itemtype="https://schema.org/Person" itemprop="author"> + <p itemprop="name"><%= post.author %></p> + </div> + <% end %> + </div> + </div> + <div class="media"> + <% if post.best_featured_image.attached? %> + <%= kamifusen_tag post.best_featured_image %> + <% end %> + </div> + </article> + <% end %> + <% end %> + </div> + <% end %> </div> </div> </section> \ No newline at end of file diff --git a/app/views/admin/communication/blocks/templates/posts/_static.html.erb b/app/views/admin/communication/blocks/templates/posts/_static.html.erb index c88c34d54acdc9ebd95ba3f82b357d9abb596cc4..167e7e361c87955622b10570652ec5db3a6da0fa 100644 --- a/app/views/admin/communication/blocks/templates/posts/_static.html.erb +++ b/app/views/admin/communication/blocks/templates/posts/_static.html.erb @@ -1,4 +1,6 @@ -<% if block.template.category %> +<% if block.template.mode == 'all' %> + all: true +<% elsif block.template.mode == 'category' && block.template.category %> category: "<%= block.template.category.path %>" <% end %> layout: <%= block.template.layout %> diff --git a/app/views/admin/communication/blocks/templates/programs/_preview.html.erb b/app/views/admin/communication/blocks/templates/programs/_preview.html.erb index adda2a10c96ddae8c77b783cac0f71414345269d..6abdb0c738143387ec6cb657c7c6b9aa22c9145f 100644 --- a/app/views/admin/communication/blocks/templates/programs/_preview.html.erb +++ b/app/views/admin/communication/blocks/templates/programs/_preview.html.erb @@ -1,16 +1,27 @@ <% -$class = "block block-programs" +class_name = "block block-programs" unless @block.title.blank? - $class += " block-with-title" + class_name += " block-with-title" end %> -<section class="<%= $class %>" style="display: none;"> + +<section class="<%= class_name %>"> <div class="container"> <div class="block-content"> + <% unless @block.title.blank? %> + <div class="top"> + <% unless @block.title.blank? %> + <h2><%= @block.title %></h2> + <% end %> + </div> + <% end %> <ol class="programs"> - <% @block.template.selected_programs.each do |program| %> + <% @block.template.elements.each do |element| + program = element.program + next if program.nil? + %> <li> - <%= program %></p> + <%= link_to program, [:admin, program] %> </li> <% end %> </ol> diff --git a/app/views/admin/communication/websites/categories/_form.html.erb b/app/views/admin/communication/websites/categories/_form.html.erb index 0769ed9a26c14933cbdd34e5b2854e2cfb62e2e1..44bb161df365955ebd7e93b56af6c48629675c52 100644 --- a/app/views/admin/communication/websites/categories/_form.html.erb +++ b/app/views/admin/communication/websites/categories/_form.html.erb @@ -4,37 +4,25 @@ <div class="row"> <div class="col-md-8"> - <div class="card flex-fill w-100"> - <div class="card-header"> - <h5 class="card-title mb-0"><%= t('content') %></h5> - </div> - <div class="card-body"> - <%= f.input :name %> - <%= render 'admin/application/summary/form', f: f, about: category %> - </div> - </div> + <%= osuny_panel t('content') do %> + <%= f.input :name %> + <%= render 'admin/application/summary/form', f: f, about: category %> + <% end %> <%= render 'admin/application/meta_description/form', f: f, about: category %> </div> <div class="col-md-4"> - <div class="card flex-fill w-100"> - <div class="card-header"> - <h5 class="card-title mb-0"><%= t('metadata') %></h5> - </div> - <div class="card-body"> - <%= f.input :slug, - as: :string, - input_html: category.persisted? ? {} : { - class: 'js-slug-input', - data: { source: '#communication_website_category_name' } - } %> - <%= f.association :parent, - collection: collection_tree(@website.categories.for_language(current_website_language), category), - label_method: ->(p) { sanitize p[:label] }, - value_method: ->(p) { p[:id] } %> - <ul> - </ul> - </div> - </div> + <%= osuny_panel t('metadata') do %> + <%= f.input :slug, + as: :string, + input_html: category.persisted? ? {} : { + class: 'js-slug-input', + data: { source: '#communication_website_category_name' } + } %> + <%= f.association :parent, + collection: collection_tree(@website.categories.for_language(current_website_language), category), + label_method: ->(p) { sanitize p[:label] }, + value_method: ->(p) { p[:id] } %> + <% end %> <%= render 'admin/application/featured_image/edit', about: category, f: f %> </div> </div> diff --git a/app/views/admin/dashboard/index.html.erb b/app/views/admin/dashboard/index.html.erb index 0fefbb6fb51ef980e4dc8affc00113c1c3edafd6..e067d7978729903f04eda3bb49b8835ec5664efc 100644 --- a/app/views/admin/dashboard/index.html.erb +++ b/app/views/admin/dashboard/index.html.erb @@ -14,14 +14,14 @@ <%= osuny_panel t('hello', name: current_user.first_name) do %> <% if current_admin_theme == 'appstack' %> <p> - Osuny a un nouveau thĆØme pour l'administration, "Pure". <br> - Voulez-vous l'essayer ? + Osuny a un nouveau thĆØme pour l'administration, "Pure". + Voulez-vous l'essayerĀ ? </p> <%= link_to 'Changer de thĆØme', admin_set_theme_path(theme: 'pure'), method: :put %> <% else %> <p> - Vous utilisez le thĆØme "Pure" pour l'administration. <br> - Voulez-vous revenir au thĆØme "Appstack" ? + Vous utilisez le thĆØme "Pure" pour l'administration. + Voulez-vous revenir au thĆØme "Appstack"Ā ? </p> <%= link_to 'Changer de thĆØme', admin_set_theme_path(theme: 'appstack'), method: :put %> <% end %> @@ -143,9 +143,6 @@ <%= link_to t("#{term}"), t("#{term}_url"), target: '_blank', rel: 'noreferrer' %> </li> <% end %> - <li class="list-inline-item"> - <%= link_to t('cookies_consent_choice'), '', class: 'js-gdpr__cookie_consent__display_again' %> - </li> </ul> </div> <% end %> diff --git a/app/views/admin/layouts/themes/_appstack.html.erb b/app/views/admin/layouts/themes/_appstack.html.erb index 331f7b38364abd8c6d9a9b7a46c14fb087a0b5b0..96264a0a66990ef247ed2d5b1fc2a8604521e200 100644 --- a/app/views/admin/layouts/themes/_appstack.html.erb +++ b/app/views/admin/layouts/themes/_appstack.html.erb @@ -27,7 +27,6 @@ </div> </div> <%= javascript_include_tag 'admin/appstack' %> - <%= render 'gdpr/cookie_consent' %> <%= render 'bugsnag' %> <%= render 'summernote_localization' %> </body> diff --git a/app/views/admin/layouts/themes/_pure.html.erb b/app/views/admin/layouts/themes/_pure.html.erb index 965029888465752746d75e9336121af843a8d2e2..b6e54cbba664e91fd9a116ee58858d6cf35de1f0 100644 --- a/app/views/admin/layouts/themes/_pure.html.erb +++ b/app/views/admin/layouts/themes/_pure.html.erb @@ -20,7 +20,6 @@ <%= render "admin/layouts/themes/pure/commands" %> <%= render "admin/layouts/themes/pure/footer" %> <%= javascript_include_tag 'admin/pure' %> - <%= render 'gdpr/cookie_consent' %> <%= render 'bugsnag' %> <%= render 'summernote_localization' %> </body> diff --git a/app/views/admin/layouts/themes/pure/_nav.html.erb b/app/views/admin/layouts/themes/pure/_nav.html.erb index 4e18def30d29207c87a930a3a8bddd84ffb88eac..5c34176bea861792e4764b0e404761586af15e82 100644 --- a/app/views/admin/layouts/themes/pure/_nav.html.erb +++ b/app/views/admin/layouts/themes/pure/_nav.html.erb @@ -42,7 +42,7 @@ context ||= :admin <div class="container-fluid"> <div class="row"> <%= render_navigation context: context, renderer: Osuny::SimpleNavigationRenderer %> - <div class="col-md-4 col-lg-3"> + <div class="col-sm-6 col-md-4 col-lg-3"> <% if current_user.picture.attached? && current_user.picture.variable? image = current_user.picture.variant(resize: '200x200') diff --git a/app/views/admin/research/journals/papers/_form.html.erb b/app/views/admin/research/journals/papers/_form.html.erb index 03c61a270834052d812d2743a72f9ded8a4000ba..b3cd705d9edf20280240a5f00234c8fbfef3cd9c 100644 --- a/app/views/admin/research/journals/papers/_form.html.erb +++ b/app/views/admin/research/journals/papers/_form.html.erb @@ -6,6 +6,7 @@ <div class="col-md-8"> <%= osuny_panel t('content') do %> <%= f.input :title, as: :text, input_html: { rows: 3 } %> + <%= f.input :summary %> <%= f.input :abstract, as: :text, input_html: { rows: 8 } %> <%= f.input :pdf %> <%= f.input :doi %> diff --git a/app/views/admin/university/organizations/show.html.erb b/app/views/admin/university/organizations/show.html.erb index ce72a0a5eba056cb9631625eddb7b0a3cd7be6b8..dccb51446de3a8d610129d8c7ca84e5fe53b5be7 100644 --- a/app/views/admin/university/organizations/show.html.erb +++ b/app/views/admin/university/organizations/show.html.erb @@ -104,12 +104,16 @@ <%= osuny_panel t('university.organization.logo') do %> <% if @organization.logo.attached? %> - <%= osuny_label University::Organization.human_attribute_name('logo') %><br> - <%= kamifusen_tag @organization.logo, class: 'img-fluid img-fill bg-light img-thumbnail p-5 mb-3' %> + <div> + <%= osuny_label University::Organization.human_attribute_name('logo') %><br> + <%= kamifusen_tag @organization.logo, class: 'img-fluid img-fill bg-light img-thumbnail p-5 mb-3' %> + </div> <% end %> <% if @organization.logo_on_dark_background.attached? %> - <%= osuny_label University::Organization.human_attribute_name('logo_on_dark_background') %><br> - <%= kamifusen_tag @organization.logo_on_dark_background, class: 'img-fluid img-fill bg-dark img-thumbnail p-5' %> + <div> + <%= osuny_label University::Organization.human_attribute_name('logo_on_dark_background') %><br> + <%= kamifusen_tag @organization.logo_on_dark_background, class: 'img-fluid img-fill bg-dark img-thumbnail p-5' %> + </div> <% end %> <% end if @organization.logo.attached? || @organization.logo_on_dark_background.attached? %> diff --git a/app/views/api/layouts/application.html.erb b/app/views/api/layouts/application.html.erb index 29a6ebea36ce213ade8cdce3702a2260918f7191..1053513aec3a9f60eb18b13556c008ad70ed8bce 100644 --- a/app/views/api/layouts/application.html.erb +++ b/app/views/api/layouts/application.html.erb @@ -23,7 +23,6 @@ <%= yield %> </main> <%= render 'footer' %> - <%= render 'gdpr/cookie_consent' %> <%= render 'bugsnag' %> </body> </html> diff --git a/app/views/application/_footer.html.erb b/app/views/application/_footer.html.erb index 530f5a966f9b8b3f19be1e545ee2823448ba94cd..abd05f1f855f16846bd4eefb57306e8110e027fc 100644 --- a/app/views/application/_footer.html.erb +++ b/app/views/application/_footer.html.erb @@ -1,27 +1,24 @@ -<footer class="pt-5"> - <div class="container text-center"> - <div class="mb-5"> +<footer class="mt-5 pt-5"> + <div class="container"> + <div class="mb-5 text-lg-center"> <%= image_tag 'osuny-black.svg', width: 80 %> </div> - <nav class="nav justify-content-center"> + <nav class="nav small d-block d-lg-flex justify-content-lg-center"> <%= link_to t('terms_of_service'), t('terms_of_service_url'), - class: 'nav-link', + class: 'nav-link ps-0', target: '_blank', rel: 'noreferrer' %> <%= link_to t('privacy_policy'), t('privacy_policy_url'), - class: 'nav-link', + class: 'nav-link ps-0', target: '_blank', rel: 'noreferrer' %> <%= link_to t('cookies_policy'), t('cookies_policy_url'), - class: 'nav-link', + class: 'nav-link ps-0', target: '_blank', rel: 'noreferrer' %> - <%= link_to t('cookies_consent_choice'), - '', - class: 'nav-link js-gdpr__cookie_consent__display_again' %> </nav> </div> </footer> diff --git a/app/views/devise/registrations/edit.html.erb b/app/views/devise/registrations/edit.html.erb index 08194d186dc16e87a888231f500e9a43dee4a33e..5bb6d917bb75447f5ad32f404aceade0130ceabe 100644 --- a/app/views/devise/registrations/edit.html.erb +++ b/app/views/devise/registrations/edit.html.erb @@ -4,7 +4,7 @@ <%= f.error_notification %> <div class="row"> - <div class="col-md-4"> + <div class="col-lg-6"> <%= f.input :email, required: true %> <%= f.input :first_name, required: true, @@ -13,15 +13,12 @@ <%= f.input :last_name, required: true, input_html: { autocomplete: "last_name" } %> - </div> - <div class="col-md-4"> <%= f.association :language, include_blank: false, label_method: lambda { |l| t("languages.#{l.iso_code.to_s}") } %> - <%= f.input :mobile_phone %> <%= f.input :admin_theme, include_blank: false %> </div> - <div class="col-md-4"> + <div class="col-lg-6"> <%= f.input :password, as: :password_with_hints, allow_password_uncloaking: true, @@ -35,6 +32,7 @@ hint: t(".leave_blank_if_you_don_t_want_to_change_it"), required: false, input_html: { autocomplete: "new-password" } %> + <%= f.input :mobile_phone %> <%= f.input :picture, as: :single_deletable_file, input_html: { accept: '.jpg,.jpeg,.png,.svg' }, diff --git a/app/views/devise/registrations/new.html.erb b/app/views/devise/registrations/new.html.erb index 34db524df5ac26e9ec94e93f7afb440ab5d695eb..cc85287f0ac19054fb0b051522e7b1684be16a12 100644 --- a/app/views/devise/registrations/new.html.erb +++ b/app/views/devise/registrations/new.html.erb @@ -6,7 +6,7 @@ <%= f.error_notification %> <div class="row"> - <div class="col-md-6"> + <div class="col-lg-6"> <%= f.input :email, required: true, input_html: { autocomplete: "email" } %> @@ -22,7 +22,7 @@ label_method: lambda { |l| t("languages.#{l.iso_code.to_s}") }, include_blank: :translate %> </div> - <div class="col-md-6"> + <div class="col-lg-6"> <%= f.input :password, as: :password_with_hints, required: true, diff --git a/app/views/devise/two_factor_authentication/show.html.erb b/app/views/devise/two_factor_authentication/show.html.erb index 964870ab3d7a2c78b0fa0198938d3c72bffb8b79..e200bb69b183fa9beed2eb58dd97691d74c7f1c1 100644 --- a/app/views/devise/two_factor_authentication/show.html.erb +++ b/app/views/devise/two_factor_authentication/show.html.erb @@ -1,6 +1,8 @@ <%= content_for :title, t('.title') %> -<h4> +<h4 class="mb-5"><%= t('.title') %></h4> + +<p> <% if resource.direct_otp %> <% if resource.direct_otp_delivery_method == 'mobile_phone' %> <%= t('devise.two_factor_authentication.enter_code_direct_otp_mobile_phone', phone: masked_phone(resource.mobile_phone)) %> @@ -10,42 +12,37 @@ <% else %> <%= t('devise.two_factor_authentication.enter_code_totp') %> <% end %> -</h4> +</p> <%= simple_form_for(resource, url: user_two_factor_authentication_path, html: { method: :put, class: 'my-3' }) do |f| %> - <div class="row"> - <div class="col-md-6"> - <div class="form-inputs"> - <div class="form-group required mt-0"> - <%= text_field_tag :code, - '', - type: 'tel', - pattern: '\d*', - required: true, - autofocus: true, - autocomplete: 'off', - class: 'form-control string required'%> - <p class="mt-2 mb-0"> - <% if resource.direct_otp %> - <%= link_to t('devise.two_factor_authentication.resend_code'), [:resend_code, resource_name, :two_factor_authentication] %> - <% else %> - <%= link_to t('devise.two_factor_authentication.send_code_instead'), [:resend_code, resource_name, :two_factor_authentication] %> - <% end %> - <% unless resource.mobile_phone.blank? # when phone is blank default code method is already :email so we don't need another link %> - ā€¢ <%= link_to t('devise.two_factor_authentication.send_email_code'), [:resend_code, resource_name, :two_factor_authentication, delivery_method: :email] %> - <% end %> - </p> - </div> - </div> - </div> - <div class="col-md-6"> - <%= link_to t('devise.shared.links.sign_out'), - destroy_user_session_path, - method: :delete, - class: "btn btn-danger float-end" %> + <div class="form-inputs"> + <div class="input-group required mt-0" style="max-width: 400px"> + <%= text_field_tag :code, + '', + type: 'tel', + pattern: '\d*', + required: true, + autofocus: true, + autocomplete: 'off', + class: 'form-control string required'%> <%= f.button :submit, t('devise.two_factor_authentication.validate'), class: "btn btn-primary" %> </div> + <p class="mt-4 mb-5"> + <% if resource.direct_otp %> + <%= link_to t('devise.two_factor_authentication.resend_code'), [:resend_code, resource_name, :two_factor_authentication] %> + <% else %> + <%= link_to t('devise.two_factor_authentication.send_code_instead'), [:resend_code, resource_name, :two_factor_authentication] %> + <% end %> + <% unless resource.mobile_phone.blank? # when phone is blank default code method is already :email so we don't need another link %> + ā€¢ <%= link_to t('devise.two_factor_authentication.send_email_code'), [:resend_code, resource_name, :two_factor_authentication, delivery_method: :email] %> + <% end %> + </p> </div> <% end %> + +<%= link_to t('devise.shared.links.sign_out'), + destroy_user_session_path, + method: :delete, + class: "btn btn-outline-danger" %> diff --git a/app/views/extranet/application/_footer.html.erb b/app/views/extranet/application/_footer.html.erb index 90c6d199b9fba77c8d58b1e512e88671c735f37f..6f774e2449b0e57f4d82608656fcf81e1aa8dd3c 100644 --- a/app/views/extranet/application/_footer.html.erb +++ b/app/views/extranet/application/_footer.html.erb @@ -45,10 +45,6 @@ about = current_extranet.about target: '_blank', rel: 'noreferrer' if current_extranet.has_cookies_policy? %> <%= link_to t('extranet.data'), data_path %> - <%= link_to t('cookies_consent_choice'), - '', - class: 'js-gdpr__cookie_consent__display_again' %> - <%= t 'extranet.osuny_html' %> </nav> </div> diff --git a/app/views/extranet/gdpr/_cookie_consent.html.erb b/app/views/extranet/gdpr/_cookie_consent.html.erb deleted file mode 100644 index 3a1cfe18e18ad1aff4e2fffef35dbf87a7a0dfd3..0000000000000000000000000000000000000000 --- a/app/views/extranet/gdpr/_cookie_consent.html.erb +++ /dev/null @@ -1,10 +0,0 @@ -<div class="gdpr__cookie_consent js-gdpr__cookie_consent"> - <div class="gdpr__cookie_consent__text"> - <%= t('gdpr.cookie_consent.text') %> - <%= t('gdpr.cookie_consent.learn_more_html', link: cookies_policy_path) %> - </div> - <div class="gdpr__cookie_consent__buttons"> - <button class="gdpr__cookie_consent__buttons__ok js-gdpr__cookie_consent__buttons__ok btn btn-primary btn-sm btn-xs"> <%= t('gdpr.cookie_consent.button_ok') %></button> - <button class="gdpr__cookie_consent__buttons__ko js-gdpr__cookie_consent__buttons__ko btn btn-primary btn-sm btn-xs"> <%= t('gdpr.cookie_consent.button_ko') %></button> - </div> -</div> \ No newline at end of file diff --git a/app/views/extranet/layouts/application.html.erb b/app/views/extranet/layouts/application.html.erb index 8b20a64470b47db0a214116ba3c18c4e12a065a1..ccad435576b5eec0aea0abed45ea8745def16a78 100644 --- a/app/views/extranet/layouts/application.html.erb +++ b/app/views/extranet/layouts/application.html.erb @@ -11,7 +11,6 @@ <%= yield %> </main> <%= render 'extranet/application/footer' %> - <%= render 'extranet/gdpr/cookie_consent' %> <%= render 'bugsnag' %> <%= javascript_include_tag 'extranet' %> <script src="https://example.osuny.org/js/extranet.js"></script> diff --git a/app/views/extranet/layouts/devise.html.erb b/app/views/extranet/layouts/devise.html.erb index f94aae6fee43e9285b0b021aa7c4ae9b779a4464..69ff30bdc1c2f7817e2ff0782323af130aab3621 100644 --- a/app/views/extranet/layouts/devise.html.erb +++ b/app/views/extranet/layouts/devise.html.erb @@ -24,12 +24,10 @@ <%= link_to t('terms_of_service'), terms_path, rel: 'noreferrer' if current_extranet.has_terms? %> <%= link_to t('privacy_policy'), privacy_policy_path, rel: 'noreferrer' if current_extranet.has_privacy_policy? %> <%= link_to t('cookies_policy'), cookies_policy_path, rel: 'noreferrer' if current_extranet.has_cookies_policy? %> - <%= link_to t('cookies_consent_choice'), '', class: 'js-gdpr__cookie_consent__display_again' %> </footer> </div> </div> </main> - <%= render 'extranet/gdpr/cookie_consent' %> <%= render 'bugsnag' %> <%= javascript_include_tag 'extranet' %> </body> diff --git a/app/views/extranet/posts/posts/show.html.erb b/app/views/extranet/posts/posts/show.html.erb index df92a2c85ad8cf28f31d9afac3f6801ebb902505..f661b233a85ae883efbb47eb52f1b0eae4c09edf 100644 --- a/app/views/extranet/posts/posts/show.html.erb +++ b/app/views/extranet/posts/posts/show.html.erb @@ -1,20 +1,32 @@ -<% content_for :title, @post %> - -<% content_for :header_right do %> - <% if @post.featured_image.attached? %> - <figure <% if @post.featured_image_credit.present? %>class="with-credit"<% end %>> - <%= kamifusen_tag @post.featured_image, class: 'img-fluid', width: 300 %> - <% if @post.featured_image_credit.present? %> - <figcaption tabindex="0"> - <%= sanitize @post.featured_image_credit %> - </figcaption> +<% content_for :header do %> + <div class="row"> + <div class="header__info col-md-8"> + <h1><%= @post %></h1> + <p class="small"> + <% if @post.published_at %> + PubliĆ© le <%= l @post.published_at.to_date, format: :long %> + <% end %> + <% if @post.category %> + <br> + Dans : <%= link_to @post.category, posts_category_path(slug: @post.category.slug), class: "link" %> + <% end %> + </p> + </div> + <div class="col-md-4"> + <% if @post.featured_image.attached? %> + <figure class="<% if @post.featured_image_credit.present? %>with-credit<% end %>"> + <%= kamifusen_tag @post.featured_image, class: 'img-fluid', width: 300 %> + <% if @post.featured_image_credit.present? %> + <figcaption tabindex="0"> + <%= sanitize @post.featured_image_credit %> + </figcaption> + <% end %> + </figure> <% end %> - </figure> - <% end %> + </div> + </div> <% end %> -<%= link_to @post.category, posts_category_path(slug: @post.category.slug) if @post.category %> - </main> <%= render 'admin/communication/blocks/preview', about: @post %> <main> diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index d7a2782bd31e89f40eb05cc1090e87caeb0b5ed7..fa8ec3ad26ada8cec7b7640605039a938125412a 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -17,7 +17,6 @@ <%= yield %> </main> <%= render 'footer' %> - <%= render 'gdpr/cookie_consent' %> <%= render 'bugsnag' %> <%= render 'summernote_localization' %> </body> diff --git a/app/views/layouts/devise.html.erb b/app/views/layouts/devise.html.erb index 6c3eb195df94f507849be3b7c6073a7cf27339bc..09a94714b1c8e7954b3b9da2e3093fe40d5a9bf9 100644 --- a/app/views/layouts/devise.html.erb +++ b/app/views/layouts/devise.html.erb @@ -12,29 +12,20 @@ </head> <body class="<%= body_classes %>"> <div class="container"> - <div class="row"> - <div class="col-sm-10 mx-auto"> - <h1 class="my-5 py-5 text-center"> - <%= link_to root_path do %> - <%= render 'logo' %> - <% end %> - </h1> - <div class="card"> - <div class="card-body text-start"> - <% unless notice.blank? %> - <div class="alert alert-success mt-2" role="alert"><%= notice.html_safe %></div> - <% end %> - <% unless alert.blank? %> - <div class="alert alert-danger mt-2" role="alert"><%= alert.html_safe %></div> - <% end %> - <%= yield %> - </div> - </div> - </div> - </div> + <h1 class="my-5 py-5 text-center"> + <%= link_to root_path do %> + <%= render 'logo' %> + <% end %> + </h1> + <% unless notice.blank? %> + <div class="alert alert-success mt-2" role="alert"><%= notice.html_safe %></div> + <% end %> + <% unless alert.blank? %> + <div class="alert alert-danger mt-2" role="alert"><%= alert.html_safe %></div> + <% end %> + <%= yield %> </div> <%= render 'footer' %> - <%= render 'gdpr/cookie_consent' %> <%= render 'bugsnag' %> <%= render 'summernote_localization' %> </body> diff --git a/config/locales/communication/en.yml b/config/locales/communication/en.yml index 0267ffb5ead36d617b465409ab5aa2d35c5ed0f9..b44050096f649c85683cbc2db8abe6fd118731ff 100644 --- a/config/locales/communication/en.yml +++ b/config/locales/communication/en.yml @@ -373,6 +373,27 @@ en: label: Iframe title (mandatory for accessibility) placeholder: Enter the title warning: Beware, the code below is used as is, without any security filtering. Be extremely careful and never integrate possibly unreliable code. + features: + description: A list of features with images (often icons) and a description. + edit: + add_element: Add feature + remove_element: Remove feature + element: + image: + label: Image (.png, .jpg, .svg) + remove: Remove image + alt: + label: Alternative text + placeholder: Enter text description + credit: + label: Credit + placeholder: Enter image's credit here + title: + label: Title + placeholder: Enter title here + description: + label: Text + placeholder: Enter text here files: description: A list of downloadable files, mentioning their file size. edit: @@ -458,6 +479,7 @@ en: cards: label: Cards description: Side by side cards, same height, strong color on rollover. Perfect for a small amount of pages. + more: Show more grid: label: Grid description: As a grid, left to right and top to bottom. @@ -532,6 +554,9 @@ en: list: label: List description: A list of posts with small images the same width. + alternate: + label: Alternate + description: Posts either on the left or on the right, composing a graphically light page. edit: add_post: Add post mode: @@ -718,6 +743,7 @@ en: datatable: Table definitions: Definitions embed: HTML embed + features: Features files: Files gallery: Gallery image: Image diff --git a/config/locales/communication/fr.yml b/config/locales/communication/fr.yml index 8794d71d438a5a77160f4ae71a1627a0e362ad1a..4d98d28791c099cf4fbcf224f3c6a77b63621cec 100644 --- a/config/locales/communication/fr.yml +++ b/config/locales/communication/fr.yml @@ -373,6 +373,27 @@ fr: label: Titre de l'iframe (nĆ©cessaire pour l'accessibilitĆ©) placeholder: Entrer le titre warning: Attention, le code ci-dessous est intĆ©grĆ© tel quel, sans filtrage de sĆ©curitĆ©. N'intĆ©grez jamais de code externe dont la fiabilitĆ© n'est pas certaine. + features: + description: Une liste de fonctionnalitĆ©s avec des images, par exemple des icĆ´nes, et une description. + edit: + add_element: Ajouter une fonctionnalitĆ© + remove_element: Supprimer la fonctionnalitĆ© + element: + image: + label: Image (.png, .jpg, .svg) + remove: Enlever l'image + alt: + label: Texte alternatif + placeholder: Entrer la description textuelle + credit: + label: CrĆ©dit + placeholder: Entrer le crĆ©dit de l'image ici + title: + label: Titre + placeholder: Entrer le titre de la fonctionnalitĆ© + description: + label: Texte + placeholder: Entrer la description de la fonctionnalitĆ© files: description: Une liste de fichiers tĆ©lĆ©chargeables, prĆ©sentĆ©s avec leur poids. edit: @@ -458,6 +479,7 @@ fr: cards: label: Cartes description: Des cartes cĆ´te Ć cĆ´te, de mĆŖme hauteur, avec une couleur forte au survol. Ce format est idĆ©al pour un petit nombre de pages. + more: En savoir plus grid: label: Grille description: Les pages sont prĆ©sentĆ©es en grille, de gauche Ć droite puis de haut en bas. @@ -532,6 +554,9 @@ fr: list: label: Liste description: Une liste d'articles avec de petites images Ć la mĆŖme largeur. + alternate: + label: Alternance + description: Une alternance trĆØs lĆ©gĆØre graphiquement d'articles entre la gauche et la droite de la page. edit: add_post: Ajouter un article mode: @@ -718,6 +743,7 @@ fr: datatable: Tableau definitions: DĆ©finitions embed: IntĆ©gration HTML + features: FonctionnalitĆ©s files: Fichiers gallery: Galerie image: Image diff --git a/config/locales/en.yml b/config/locales/en.yml index 91169d4178a01d62dd536c08878967686b2177a3..551e5fb3b8104a64070910aec3a0232cf3e89bd9 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -201,8 +201,6 @@ en: empty: Folder is empty open: Open folder close: Close folder - gdpr: - privacy_policy: https://osuny.org/politique-de-confidentialite hello: "Hello %{name}!" home: Home imports: diff --git a/config/locales/fr.yml b/config/locales/fr.yml index d978aafc97311eaa4f3f2004d0d1bf71dbb4ed48..1fc37088e5c8ff952d9534c617e994326808d2da 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -201,8 +201,6 @@ fr: empty: Le dossier est vide open: Ouvrir le dossier close: Fermer le dossier - gdpr: - privacy_policy: https://osuny.org/politique-de-confidentialite hello: "Bonjour %{name}Ā !" home: Accueil imports: diff --git a/db/schema.rb b/db/schema.rb index 024cee19b2ef8cefd8186932d3216cfcb3fae815..320e151e6fb186a723a9866d48b3d63c7a50ff5c 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -16,7 +16,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_04_05_142031) do enable_extension "plpgsql" enable_extension "unaccent" - create_table "action_text_rich_texts", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "action_text_rich_texts", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.string "name", null: false t.text "body" t.string "record_type", null: false @@ -26,7 +26,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_04_05_142031) do t.index ["record_type", "record_id", "name"], name: "index_action_text_rich_texts_uniqueness", unique: true end - create_table "active_storage_attachments", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "active_storage_attachments", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.string "name", null: false t.string "record_type", null: false t.uuid "record_id", null: false @@ -36,7 +36,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_04_05_142031) do t.index ["record_type", "record_id", "name", "blob_id"], name: "index_active_storage_attachments_uniqueness", unique: true end - create_table "active_storage_blobs", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "active_storage_blobs", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.string "key", null: false t.string "filename", null: false t.string "content_type" @@ -50,13 +50,13 @@ ActiveRecord::Schema[7.0].define(version: 2023_04_05_142031) do t.index ["university_id"], name: "index_active_storage_blobs_on_university_id" end - create_table "active_storage_variant_records", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "active_storage_variant_records", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.uuid "blob_id", null: false t.string "variation_digest", null: false t.index ["blob_id", "variation_digest"], name: "index_active_storage_variant_records_uniqueness", unique: true end - create_table "administration_qualiopi_criterions", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "administration_qualiopi_criterions", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.integer "number" t.text "name" t.text "description" @@ -64,7 +64,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_04_05_142031) do t.datetime "updated_at", null: false end - create_table "administration_qualiopi_indicators", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "administration_qualiopi_indicators", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.uuid "criterion_id", null: false t.integer "number" t.text "name" @@ -78,7 +78,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_04_05_142031) do t.index ["criterion_id"], name: "index_administration_qualiopi_indicators_on_criterion_id" end - create_table "communication_blocks", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "communication_blocks", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.uuid "university_id", null: false t.string "about_type" t.uuid "about_id" @@ -175,7 +175,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_04_05_142031) do t.index ["university_id"], name: "index_communication_extranet_posts_on_university_id" end - create_table "communication_extranets", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "communication_extranets", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.string "name" t.uuid "university_id", null: false t.string "host" @@ -203,11 +203,12 @@ ActiveRecord::Schema[7.0].define(version: 2023_04_05_142031) do t.text "home_sentence" t.text "sass" t.text "css" + t.boolean "allow_experiences_modification", default: true t.index ["about_type", "about_id"], name: "index_communication_extranets_on_about" t.index ["university_id"], name: "index_communication_extranets_on_university_id" end - create_table "communication_website_categories", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "communication_website_categories", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.uuid "university_id", null: false t.uuid "communication_website_id", null: false t.string "name" @@ -256,7 +257,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_04_05_142031) do t.index ["website_id"], name: "index_communication_website_connections_on_website_id" end - create_table "communication_website_git_files", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "communication_website_git_files", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.string "previous_path" t.string "about_type", null: false t.uuid "about_id", null: false @@ -268,7 +269,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_04_05_142031) do t.index ["website_id"], name: "index_communication_website_git_files_on_website_id" end - create_table "communication_website_imported_authors", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "communication_website_imported_authors", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.uuid "university_id", null: false t.uuid "website_id", null: false t.uuid "author_id" @@ -284,7 +285,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_04_05_142031) do t.index ["website_id"], name: "idx_communication_website_imported_auth_on_website" end - create_table "communication_website_imported_categories", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "communication_website_imported_categories", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.uuid "university_id", null: false t.uuid "website_id", null: false t.uuid "category_id" @@ -302,7 +303,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_04_05_142031) do t.index ["website_id"], name: "idx_communication_website_imported_cat_on_website" end - create_table "communication_website_imported_media", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "communication_website_imported_media", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.string "identifier" t.jsonb "data" t.text "file_url" @@ -317,7 +318,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_04_05_142031) do t.index ["website_id"], name: "index_communication_website_imported_media_on_website_id" end - create_table "communication_website_imported_pages", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "communication_website_imported_pages", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.uuid "university_id", null: false t.uuid "website_id", null: false t.uuid "page_id" @@ -341,7 +342,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_04_05_142031) do t.index ["website_id"], name: "index_communication_website_imported_pages_on_website_id" end - create_table "communication_website_imported_posts", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "communication_website_imported_posts", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.uuid "university_id", null: false t.uuid "website_id", null: false t.uuid "post_id" @@ -366,7 +367,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_04_05_142031) do t.index ["website_id"], name: "index_communication_website_imported_posts_on_website_id" end - create_table "communication_website_imported_websites", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "communication_website_imported_websites", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.uuid "university_id", null: false t.uuid "website_id", null: false t.integer "status", default: 0 @@ -376,7 +377,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_04_05_142031) do t.index ["website_id"], name: "index_communication_website_imported_websites_on_website_id" end - create_table "communication_website_menu_items", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "communication_website_menu_items", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.uuid "university_id", null: false t.uuid "website_id", null: false t.uuid "menu_id", null: false @@ -396,7 +397,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_04_05_142031) do t.index ["website_id"], name: "index_communication_website_menu_items_on_website_id" end - create_table "communication_website_menus", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "communication_website_menus", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.uuid "university_id", null: false t.uuid "communication_website_id", null: false t.string "title" @@ -412,7 +413,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_04_05_142031) do t.index ["university_id"], name: "index_communication_website_menus_on_university_id" end - create_table "communication_website_pages", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "communication_website_pages", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.uuid "university_id", null: false t.uuid "communication_website_id", null: false t.string "title" @@ -458,7 +459,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_04_05_142031) do t.index ["website_id"], name: "index_communication_website_permalinks_on_website_id" end - create_table "communication_website_posts", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "communication_website_posts", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.uuid "university_id", null: false t.uuid "communication_website_id", null: false t.string "title" @@ -484,7 +485,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_04_05_142031) do t.index ["university_id"], name: "index_communication_website_posts_on_university_id" end - create_table "communication_websites", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "communication_websites", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.uuid "university_id", null: false t.string "name" t.string "url" @@ -536,7 +537,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_04_05_142031) do t.index ["priority", "run_at"], name: "delayed_jobs_priority" end - create_table "education_academic_years", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "education_academic_years", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.uuid "university_id", null: false t.integer "year" t.datetime "created_at", null: false @@ -551,7 +552,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_04_05_142031) do 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| + create_table "education_cohorts", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.uuid "university_id", null: false t.uuid "program_id", null: false t.uuid "academic_year_id", null: false @@ -572,7 +573,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_04_05_142031) do t.index ["university_person_id", "education_cohort_id"], name: "index_person_cohort" end - create_table "education_diplomas", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "education_diplomas", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.string "name" t.string "short_name" t.integer "level", default: 0 @@ -586,7 +587,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_04_05_142031) do t.index ["university_id"], name: "index_education_diplomas_on_university_id" end - create_table "education_programs", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "education_programs", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.uuid "university_id", null: false t.string "name" t.integer "capacity" @@ -646,7 +647,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_04_05_142031) do t.index ["education_program_id", "user_id"], name: "index_education_programs_users_on_program_id_and_user_id" end - create_table "education_schools", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "education_schools", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.uuid "university_id", null: false t.string "name" t.string "address" @@ -662,7 +663,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_04_05_142031) do t.index ["university_id"], name: "index_education_schools_on_university_id" end - create_table "imports", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "imports", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.integer "number_of_lines" t.jsonb "processing_errors" t.integer "kind" @@ -675,7 +676,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_04_05_142031) do t.index ["user_id"], name: "index_imports_on_user_id" end - create_table "languages", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "languages", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.string "name" t.string "iso_code" t.datetime "created_at", null: false @@ -742,7 +743,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_04_05_142031) do t.index ["university_id"], name: "index_research_journal_paper_kinds_on_university_id" end - create_table "research_journal_papers", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "research_journal_papers", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.string "title" t.datetime "published_at", precision: nil t.uuid "university_id", null: false @@ -779,7 +780,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_04_05_142031) do t.index ["researcher_id"], name: "index_research_journal_papers_researchers_on_researcher_id" end - create_table "research_journal_volumes", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "research_journal_volumes", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.uuid "university_id", null: false t.uuid "research_journal_id", null: false t.string "title" @@ -799,7 +800,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_04_05_142031) do t.index ["university_id"], name: "index_research_journal_volumes_on_university_id" end - create_table "research_journals", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "research_journals", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.uuid "university_id", null: false t.string "title" t.text "meta_description" @@ -810,7 +811,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_04_05_142031) do t.index ["university_id"], name: "index_research_journals_on_university_id" end - create_table "research_laboratories", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "research_laboratories", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.uuid "university_id", null: false t.string "name" t.string "address" @@ -822,7 +823,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_04_05_142031) do t.index ["university_id"], name: "index_research_laboratories_on_university_id" end - create_table "research_laboratory_axes", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "research_laboratory_axes", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.uuid "university_id", null: false t.uuid "research_laboratory_id", null: false t.string "name" @@ -836,7 +837,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_04_05_142031) do t.index ["university_id"], name: "index_research_laboratory_axes_on_university_id" end - create_table "research_theses", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "research_theses", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.uuid "university_id", null: false t.uuid "research_laboratory_id", null: false t.uuid "author_id", null: false @@ -854,7 +855,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_04_05_142031) do t.index ["university_id"], name: "index_research_theses_on_university_id" end - create_table "universities", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "universities", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.string "name" t.string "identifier" t.string "address" @@ -893,7 +894,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_04_05_142031) do t.index ["university_id"], name: "index_university_organization_categories_on_university_id" end - create_table "university_organizations", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "university_organizations", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.uuid "university_id", null: false t.string "name" t.string "long_name" @@ -931,7 +932,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_04_05_142031) do t.index ["organization_id"], name: "index_university_organizations_categories_on_organization_id" end - create_table "university_people", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "university_people", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.uuid "university_id", null: false t.uuid "user_id" t.string "last_name" @@ -987,7 +988,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_04_05_142031) do t.index ["university_id"], name: "index_university_person_categories_on_university_id" end - create_table "university_person_experiences", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "university_person_experiences", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.uuid "university_id", null: false t.uuid "person_id", null: false t.uuid "organization_id", null: false @@ -1001,7 +1002,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_04_05_142031) do t.index ["university_id"], name: "index_university_person_experiences_on_university_id" end - create_table "university_person_involvements", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "university_person_involvements", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.uuid "university_id", null: false t.uuid "person_id", null: false t.integer "kind" @@ -1016,7 +1017,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_04_05_142031) do t.index ["university_id"], name: "index_university_person_involvements_on_university_id" end - create_table "university_roles", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "university_roles", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.uuid "university_id", null: false t.string "target_type" t.uuid "target_id" @@ -1028,7 +1029,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_04_05_142031) do t.index ["university_id"], name: "index_university_roles_on_university_id" end - create_table "users", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "users", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.uuid "university_id", null: false t.string "first_name" t.string "last_name" diff --git a/lib/tasks/auto.rake b/lib/tasks/auto.rake index 2af83edd413a6606b88da8be7ed8347334287cc4..cc68e377221307d291395a01a8fbee6c05e0dc91 100644 --- a/lib/tasks/auto.rake +++ b/lib/tasks/auto.rake @@ -1,11 +1,8 @@ namespace :auto do + desc 'Update publications from HAL for all researchers' task update_hal: :environment do Research::Hal.update_from_api! end - desc 'Save all websites to update connections and clean Git repositories' - task save_and_sync_websites: :environment do - Communication::Website.save_and_sync_websites! - end end \ No newline at end of file diff --git a/test/fixtures/communication/blocks.yml b/test/fixtures/communication/blocks.yml index 0a0c4a5f730950692e674446a6d394b837c298d5..a60600f67229ea5c6b01309153463389d40205eb 100644 --- a/test/fixtures/communication/blocks.yml +++ b/test/fixtures/communication/blocks.yml @@ -12,19 +12,16 @@ # created_at :datetime not null # updated_at :datetime not null # about_id :uuid indexed => [about_type] -# heading_id :uuid indexed # university_id :uuid not null, indexed # # Indexes # -# index_communication_blocks_on_heading_id (heading_id) # index_communication_blocks_on_university_id (university_id) # index_communication_website_blocks_on_about (about_type,about_id) # # Foreign Keys # # fk_rails_18291ef65f (university_id => universities.id) -# fk_rails_90ac986fab (heading_id => communication_block_headings.id) # olivia_in_noesya: diff --git a/test/fixtures/communication/extranets.yml b/test/fixtures/communication/extranets.yml index c4a72564511a4905256b44eff1b90d9ad95d76db..5b00f559b78ac19b9a3871e2736923e92e325c4b 100644 --- a/test/fixtures/communication/extranets.yml +++ b/test/fixtures/communication/extranets.yml @@ -2,34 +2,35 @@ # # Table name: communication_extranets # -# id :uuid not null, primary key -# about_type :string indexed => [about_id] -# color :string -# cookies_policy :text -# css :text -# feature_alumni :boolean default(FALSE) -# feature_contacts :boolean default(FALSE) -# feature_jobs :boolean default(FALSE) -# feature_library :boolean default(FALSE) -# feature_posts :boolean default(FALSE) -# has_sso :boolean default(FALSE) -# home_sentence :text -# host :string -# name :string -# privacy_policy :text -# registration_contact :string -# sass :text -# sso_button_label :string -# sso_cert :text -# sso_mapping :jsonb -# sso_name_identifier_format :string -# sso_provider :integer default("saml") -# sso_target_url :string -# terms :text -# created_at :datetime not null -# updated_at :datetime not null -# about_id :uuid indexed => [about_type] -# university_id :uuid not null, indexed +# id :uuid not null, primary key +# about_type :string indexed => [about_id] +# allow_experiences_modification :boolean default(TRUE) +# color :string +# cookies_policy :text +# css :text +# feature_alumni :boolean default(FALSE) +# feature_contacts :boolean default(FALSE) +# feature_jobs :boolean default(FALSE) +# feature_library :boolean default(FALSE) +# feature_posts :boolean default(FALSE) +# has_sso :boolean default(FALSE) +# home_sentence :text +# host :string +# name :string +# privacy_policy :text +# registration_contact :string +# sass :text +# sso_button_label :string +# sso_cert :text +# sso_mapping :jsonb +# sso_name_identifier_format :string +# sso_provider :integer default("saml") +# sso_target_url :string +# terms :text +# created_at :datetime not null +# updated_at :datetime not null +# about_id :uuid indexed => [about_type] +# university_id :uuid not null, indexed # # Indexes # diff --git a/test/fixtures/communication/website/menus.yml b/test/fixtures/communication/website/menus.yml new file mode 100644 index 0000000000000000000000000000000000000000..51d442523ed21780b78d5634352551aa4485d8cc --- /dev/null +++ b/test/fixtures/communication/website/menus.yml @@ -0,0 +1,34 @@ +# == Schema Information +# +# Table name: communication_website_menus +# +# id :uuid not null, primary key +# github_path :text +# identifier :string +# title :string +# created_at :datetime not null +# updated_at :datetime not null +# communication_website_id :uuid not null, indexed +# language_id :uuid not null, indexed +# original_id :uuid indexed +# university_id :uuid not null, indexed +# +# Indexes +# +# idx_comm_website_menus_on_communication_website_id (communication_website_id) +# index_communication_website_menus_on_language_id (language_id) +# index_communication_website_menus_on_original_id (original_id) +# index_communication_website_menus_on_university_id (university_id) +# +# Foreign Keys +# +# fk_rails_2901ebb799 (original_id => communication_website_menus.id) +# fk_rails_4d43d36541 (language_id => languages.id) +# fk_rails_8d6227916e (university_id => universities.id) +# fk_rails_dcc7198fc5 (communication_website_id => communication_websites.id) +# +primary_menu: + university: default_university + website: website_with_github + title: 'Menu principal' + language: fr diff --git a/test/models/communication/website/connection_test.rb b/test/models/communication/website/connection_test.rb new file mode 100644 index 0000000000000000000000000000000000000000..57d808e5b411ed08f82c91918c5cd0b3686bb39a --- /dev/null +++ b/test/models/communication/website/connection_test.rb @@ -0,0 +1,193 @@ +# == Schema Information +# +# Table name: communication_website_connections +# +# id :uuid not null, primary key +# direct_source_type :string indexed => [direct_source_id] +# indirect_object_type :string not null, indexed => [indirect_object_id] +# created_at :datetime not null +# updated_at :datetime not null +# direct_source_id :uuid indexed => [direct_source_type] +# indirect_object_id :uuid not null, indexed => [indirect_object_type] +# university_id :uuid not null, indexed +# website_id :uuid not null, indexed +# +# Indexes +# +# index_communication_website_connections_on_object (indirect_object_type,indirect_object_id) +# index_communication_website_connections_on_source (direct_source_type,direct_source_id) +# index_communication_website_connections_on_university_id (university_id) +# index_communication_website_connections_on_website_id (website_id) +# +# Foreign Keys +# +# fk_rails_728034883b (website_id => communication_websites.id) +# fk_rails_bd1ac8383b (university_id => universities.id) +# +require "test_helper" + +# rails test test/models/communication/website/connection_test.rb +class Communication::Website::ConnectionTest < ActiveSupport::TestCase + def test_unpublish_indirect_does_nothing + page = communication_website_pages(:page_with_no_dependency) + setup_page_connections(page) + + # On dĆ©publie un bloc : +0 + assert_no_difference("Communication::Website::Connection.count") do + page.blocks.second.update(published: false) + end + end + + def test_unpublish_direct_does_nothing + page = communication_website_pages(:page_with_no_dependency) + setup_page_connections(page) + + # On dĆ©publie la page ayant un bloc chapitre : +0 + assert_no_difference("Communication::Website::Connection.count") do + page.update(published: false) + end + end + + def test_deleting_direct_removes_all_its_connections + page = communication_website_pages(:page_with_no_dependency) + setup_page_connections(page) + + # On supprime la page ayant un bloc chapitre, et ainsi toutes ses connexions : -10 + assert_difference -> { Communication::Website::Connection.count } => -10 do + page.destroy + end + end + + def test_deleting_indirect_removes_all_its_connections + page = communication_website_pages(:page_with_no_dependency) + setup_page_connections(page) + + # On supprime le bloc qui contient PA : -2 (parce que PA doit ĆŖtre supprimĆ© aussi) + assert_difference -> { Communication::Website::Connection.count } => -2 do + page.blocks.find_by(position: 2).destroy + end + end + + def test_deleting_indirect_with_a_dependency_having_two_sources + page = communication_website_pages(:page_with_no_dependency) + setup_page_connections(page) + + # On ajoute noesya Ć PA via un block "Organisations" + assert_difference -> { Communication::Website::Connection.count } => 1 do + block = pa.blocks.create(position: 1, published: true, template_kind: :partners) + block.data = "{ \"elements\": [ { \"id\": \"#{noesya.id}\" } ] }" + block.save + end + + # Suppression d'un objet indirect qui a en dĆ©pendance un autre objet utilisĆ© ailleurs (dans le cas prĆ©cĆ©dent si PA Ć©tait utilisĆ© par une autre source) + # On supprime le bloc qui contient PA : -3 (parce que PA doit ĆŖtre supprimĆ© aussi ainsi que son bloc Organisations mais pas Noesya, toujours connectĆ©e via le block 3) + assert_difference -> { Communication::Website::Connection.count } => -3 do + page.blocks.find_by(position: 2).destroy + end + end + + def test_unpublish_indirect_does_nothing + page = communication_website_pages(:page_with_no_dependency) + setup_page_connections(page) + + # On dĆ©publie la page ayant un bloc chapitre : +0 + assert_no_difference("Communication::Website::Connection.count") do + page.blocks.ordered.last.update(published: false) + end + end + + def test_deleting_direct_with_indirect_dependency_having_two_sources + # https://developers.osuny.org/docs/admin/communication/sites-web/dependencies/iteration-4/#olivia-et-le-saumon-de-schr%C3%B6dinger + page = communication_website_pages(:page_with_no_dependency) + setup_page_connections(page) + + second_page = communication_website_pages(:page_test) + block = second_page.blocks.create(position: 1, published: true, template_kind: :partners) + block.data = "{ \"elements\": [ { \"id\": \"#{noesya.id}\" } ] }" + block.save + + # Noesya est connectĆ©e via les 2 pages, donc 2 connexions + assert_equal 2, page.website.connections.where(indirect_object: noesya).count + + # On supprime la 2e page, donc ses 7 connexions Ć savoir : + # - Le block Organisations et Noesya (2) + # - Les 5 connexions via Noesya, Ć savoir : + # - Le block Personnes avec Olivia et son block Organisations (3) + # note : Pas Noesya car la connexion existe dĆ©jĆ plus haut + # - Le block Personnes avec Arnaud (2) + assert_difference -> { Communication::Website::Connection.count } => -7 do + second_page.destroy + end + + # Noesya est toujours connectĆ©e via la 1re page + assert_equal 1, page.website.connections.where(indirect_object: noesya).count + end + + def test_connecting_and_disconnecting_indirect_to_website_directly + # En connectant l'Ć©cole au site, on crĆ©e une connexion pour ses 2 objets ainsi que les dĆ©pendances de l'Ć©cole : + # Ses formations (default_program) et ses diplĆ´mes (default_diploma) : donc 3 connexions au total + assert_difference -> { Communication::Website::Connection.count } => 3 do + website_with_github.update(about: default_school) + end + + # En dĆ©connectant l'Ć©cole du site, on supprime les connexions crĆ©Ć©es prĆ©cĆ©demment + assert_difference -> { Communication::Website::Connection.count } => -3 do + website_with_github.update(about: nil) + end + end + + private + + def setup_page_connections(page) + assert_no_difference("Communication::Website::Connection.count") do + page.save + end + + # On ajoute un block "Chapitre" : +1 + assert_difference -> { Communication::Website::Connection.count } => 1 do + page.blocks.create(position: 1, published: true, template_kind: :chapter) + end + + # On connecte PA via un block "Personnes" : +2 + assert_difference -> { Communication::Website::Connection.count } => 2 do + block = page.blocks.create(position: 2, published: true, template_kind: :organization_chart) + block.data = "{ \"elements\": [ { \"id\": \"#{pa.id}\" } ] }" + block.save + end + + # On ajoute noesya via un block "Organisations" : +4 parce que noesya a un block "Personnes" avec Olivia + assert_difference -> { Communication::Website::Connection.count } => 4 do + block = page.blocks.create(position: 3, published: true, template_kind: :partners) + block.data = "{ \"elements\": [ { \"id\": \"#{noesya.id}\" } ] }" + block.save + end + + # On ajoute Arnaud Ć noesya via un block "Personnes" : +2 + assert_difference -> { Communication::Website::Connection.count } => 2 do + block = noesya.blocks.create(position: 2, published: true, template_kind: :organization_chart) + block.data = "{ \"elements\": [ { \"id\": \"#{arnaud.id}\" } ] }" + block.save + end + + # On tente la boucle infine en ajoutant noesya Ć Olivia : +1 (le block ajoutĆ© Ć Olivia) + assert_difference -> { Communication::Website::Connection.count } => 1 do + block = olivia.blocks.create(position: 1, published: true, template_kind: :partners) + block.data = "{ \"elements\": [ { \"id\": \"#{noesya.id}\" } ] }" + block.save + end + + # La page est donc comme ceci + # Page + # - Block Chapitre + # - Block Personnes + # - PA + # - Block Organisations + # - Noesya + # - Block Personnes + # - Olivia + # - Block Organisations + # - Noesya + # - Block Personnes + # - Arnaud + end +end diff --git a/test/models/communication/website/dependencies_test.rb b/test/models/communication/website/dependencies_test.rb deleted file mode 100644 index a1245d7624cd903df9cea788ce56284971bb5bec..0000000000000000000000000000000000000000 --- a/test/models/communication/website/dependencies_test.rb +++ /dev/null @@ -1,15 +0,0 @@ -require "test_helper" - -# rails test test/models/communication/website/dependencies_test.rb -class Communication::Website::DependenciesTest < ActiveSupport::TestCase - test "page" do - # Rien : 0 dĆ©pendances - page = communication_website_pages(:page_with_no_dependency) - assert_equal 0, page.recursive_dependencies.count - - # On ajoute un block "Chapitre" : 7 dĆ©pendances (les 6 composants du chapitre + le chapitre) - page = communication_website_pages(:page_with_no_dependency) - page.blocks.create(position: 1, published: true, template_kind: :chapter) - assert_equal 7, page.recursive_dependencies.count - end -end diff --git a/test/models/communication/website/dependency_test.rb b/test/models/communication/website/dependency_test.rb new file mode 100644 index 0000000000000000000000000000000000000000..ce703c6f429a6b8c2d6a7e5e181efd36fbe7ebb0 --- /dev/null +++ b/test/models/communication/website/dependency_test.rb @@ -0,0 +1,95 @@ +require "test_helper" + +# rails test test/models/communication/website/dependency_test.rb +class Communication::Website::DependencyTest < ActiveSupport::TestCase + def test_page_dependencies + # Rien : 0 dĆ©pendances + page = communication_website_pages(:page_with_no_dependency) + assert_equal 0, page.recursive_dependencies.count + + # On ajoute un block "Chapitre" : 7 dĆ©pendances (les 6 composants du chapitre + le block lui mĆŖme) + page.blocks.create(position: 1, published: true, template_kind: :chapter) + assert_equal 7, page.recursive_dependencies.count + end + + def test_change_block_dependencies + page = communication_website_pages(:page_with_no_dependency) + + # On ajoute un block Personnes liĆ© Ć Arnaud : 9 dĆ©pendances + # - le block Personnes (1) + # - 4 composants du template du block + 1 Ć©lĆ©ment (5) + # - 2 composants de l'Ć©lĆ©ment du template (2) + # - la personne en dĆ©pendance du composant Person (1) + block = page.blocks.create(position: 1, published: true, template_kind: :organization_chart) + block.data = "{ \"elements\": [ { \"id\": \"#{arnaud.id}\" } ] }" + block.save + + page = page.reload + + assert_equal 9, page.recursive_dependencies.count + + # On modifie le target du block + Delayed::Job.destroy_all + block.data = "{ \"elements\": [ { \"id\": \"#{olivia.id}\" } ] }" + block.save + # On vĆ©rifie qu'on appelle bien la mĆ©thode destroy_obsolete_git_files sur le site de la page + assert(destroy_obsolete_git_files_job) + + assert_equal 9, page.recursive_dependencies.count + + # VĆ©rifie qu'on a bien une tĆ¢che de nettoyage si le block est supprimĆ© + Delayed::Job.destroy_all + block.destroy + assert(destroy_obsolete_git_files_job) + + end + + def test_change_website_dependencies + dependencies_before_count = website_with_github.recursive_dependencies.count + + # On modifie l'about du website en ajoutant une Ć©cole + website_with_github.update(about: default_school) + refute(destroy_obsolete_git_files_job) + delta = website_with_github.recursive_dependencies.count - dependencies_before_count + assert_equal 12, delta + + Delayed::Job.destroy_all + + # On enlĆØve l'about du website + website_with_github.update(about: nil) + + # On vĆ©rifie qu'on appelle bien la mĆ©thode destroy_obsolete_git_files sur le site + assert(destroy_obsolete_git_files_job) + + end + + def test_change_menu_item_dependencies + menu = communication_website_menus(:primary_menu) + + item = menu.items.create(university: default_university, website: website_with_github, kind: :blank, title: 'Test') + assert_equal 2, item.recursive_dependencies.count + + item.kind = :page + item.about = communication_website_pages(:page_with_no_dependency) + item.save + assert_equal 2, item.recursive_dependencies.count + + # Comme les menu items ne rĆ©pondent pas Ć is_direct_object? du coup aucune tĆ¢che de nettoyage n'est ajoutĆ©e + item.destroy + refute(destroy_obsolete_git_files_job) + end + + protected + + def destroy_obsolete_git_files_job(website_id = website_with_github.id) + find_performable_method_job(:destroy_obsolete_git_files_without_delay, website_id) + end + + # On ne peut pas utiliser assert_enqueued_jobs sur les mĆ©thodes asynchrones gĆ©rĆ©es avec handle_asynchronously + def find_performable_method_job(method, id) + Delayed::Job.all.detect { |job| + job.payload_object.method_name == method && + job.payload_object.object.id == id + } + end +end diff --git a/test/test_helper.rb b/test/test_helper.rb index 6aba439556b595ffef2e854cf46438a608933078..34de059cec8a1965cbb4581fbcb3e05fd5e64531 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -26,6 +26,14 @@ class ActiveSupport::TestCase @default_extranet ||= communication_extranets(:default_extranet) end + def website_with_github + @website_with_github ||= communication_websites(:website_with_github) + end + + def default_school + @default_school ||= education_schools(:default_school) + end + def alumnus @alumnus ||= users(:alumnus) end