diff --git a/app/assets/javascripts/admin/commons/batch-selectable.js b/app/assets/javascripts/admin/commons/batch-selectable.js new file mode 100644 index 0000000000000000000000000000000000000000..09f9f4f6c896865bf5639443f4c6acc33a2d39a3 --- /dev/null +++ b/app/assets/javascripts/admin/commons/batch-selectable.js @@ -0,0 +1,35 @@ +/* global */ +window.osuny.BatchSelectable = function BatchSelectable (element) { + 'use strict'; + this.element = element; + this.selectAllInput = this.element.querySelector('[data-batch-selectable-role="select-all"]'); + this.selectSingleInputs = this.element.querySelectorAll('[data-batch-selectable-role="select-single"]'); + this.initEvents(); +}; + +window.osuny.BatchSelectable.prototype.initEvents = function () { + 'use strict'; + if (this.selectAllInput === null) { + return; + } + this.selectAllInput.addEventListener('change', function () { + this.toggleSingleInputs(this.selectAllInput.checked); + }.bind(this)); +}; + +window.osuny.BatchSelectable.prototype.toggleSingleInputs = function (checked) { + 'use strict'; + var i; + for (i = 0; i < this.selectSingleInputs.length; i += 1) { + this.selectSingleInputs[i].checked = checked; + } +}; + +window.addEventListener('DOMContentLoaded', function () { + 'use strict'; + var elements = document.querySelectorAll('[data-batch-selectable]'), + i; + for (i = 0; i < elements.length; i += 1) { + new window.osuny.BatchSelectable(elements[i]); + } +}); diff --git a/app/controllers/admin/communication/website/posts_controller.rb b/app/controllers/admin/communication/website/posts_controller.rb index 2c515e621523a213fa4cf4cece6a196481fed6ec..ef64565104f4a3bcaac82da9439e1401a002ea04 100644 --- a/app/controllers/admin/communication/website/posts_controller.rb +++ b/app/controllers/admin/communication/website/posts_controller.rb @@ -6,6 +6,19 @@ class Admin::Communication::Website::PostsController < Admin::Communication::Web breadcrumb end + def publish + ids = params[:ids] || [] + target_posts = @website.posts.where(id: ids) + if params[:published] == "true" + target_posts.update(published: true) + elsif params[:published] == "false" + target_posts.update(published: false) + end + @website.sync_objects_with_git(target_posts) if target_posts.any? + redirect_back fallback_location: admin_communication_website_posts_path, + notice: t('communication.website.posts.successful_batch_update') + end + def show breadcrumb end diff --git a/app/models/communication/website/with_git_repository.rb b/app/models/communication/website/with_git_repository.rb index 436b1f64ef663f438eff86b1efabc1e93b935e83..1339143e00a5abb1cb3b51e66101999934732bd1 100644 --- a/app/models/communication/website/with_git_repository.rb +++ b/app/models/communication/website/with_git_repository.rb @@ -10,4 +10,18 @@ module Communication::Website::WithGitRepository def git_repository @git_repository ||= Git::Repository.new self end + + def sync_objects_with_git(objects) + touch + return unless git_repository.valid? + objects.each do |object| + next unless object.has_website_for_self?(self) + dependencies = object.git_dependencies(self).to_a.flatten.uniq.compact + dependencies.each do |dependency| + Communication::Website::GitFile.sync self, dependency + end + end + git_repository.sync! + end + handle_asynchronously :sync_objects_with_git, queue: 'default' end diff --git a/app/models/concerns/with_git.rb b/app/models/concerns/with_git.rb index 174e5b227789f34b95b0bd1d5f1baf3ec1646eca..0b6845c2e1381f48f5c50a4c527cc665a2e28ce0 100644 --- a/app/models/concerns/with_git.rb +++ b/app/models/concerns/with_git.rb @@ -64,6 +64,18 @@ module WithGit end end + def has_website_for_self?(website) + websites_for_self.include?(website) + end + + def git_dependencies(website = nil) + [self] + end + + def git_destroy_dependencies(website = nil) + [self] + end + protected def in_block_dependencies?(website) @@ -83,12 +95,4 @@ module WithGit [] end end - - def git_dependencies(website = nil) - [self] - end - - def git_destroy_dependencies(website = nil) - [self] - end end diff --git a/app/views/admin/communication/website/posts/_list.html.erb b/app/views/admin/communication/website/posts/_list.html.erb index 61f78aa6ced46a4de5dcf6c09a939a47100357da..8ebc3a67791990b8cd12e8238044fc6772047791 100644 --- a/app/views/admin/communication/website/posts/_list.html.erb +++ b/app/views/admin/communication/website/posts/_list.html.erb @@ -1,10 +1,16 @@ <% hide_author |= false hide_category |= false + selectable |= false %> -<table class="<%= table_classes %>"> +<table class="<%= table_classes %>" <%= "data-batch-selectable" if selectable %>> <thead> <tr> + <% if selectable %> + <th> + <%= check_box_tag nil, nil, false, data: { batch_selectable_role: "select-all" } %> + </th> + <% end %> <th><%= Communication::Website::Post.human_attribute_name('title') %></th> <th><%= Communication::Website::Post.human_attribute_name('featured_image') %></th> <% unless hide_author %> @@ -20,6 +26,11 @@ <tbody> <% posts.each do |post| %> <tr> + <% if selectable %> + <td> + <%= check_box_tag "ids[]", post.id, false, data: { batch_selectable_role: "select-single" } %> + </td> + <% end %> <td><%= link_to post, admin_communication_website_post_path(website_id: post.website.id, id: post.id), class: "#{'opacity-50' unless post.published?}" %></td> diff --git a/app/views/admin/communication/website/posts/index.html.erb b/app/views/admin/communication/website/posts/index.html.erb index 814a431bf51ab1da6c16ae00eb1bec4d3504f962..51b31b48864c64137ad52ee6d21b65743f937b15 100644 --- a/app/views/admin/communication/website/posts/index.html.erb +++ b/app/views/admin/communication/website/posts/index.html.erb @@ -2,10 +2,29 @@ <%= render 'admin/communication/websites/sidebar' do %> <div class="card"> - <%= render 'admin/communication/website/posts/list', posts: @posts, hide_author: true %> - <% if @posts.total_pages > 1 %> + <%= form_tag publish_admin_communication_website_posts_path do %> + <input type="hidden" name="ids[]" value=""> + <%= render 'admin/communication/website/posts/list', posts: @posts, hide_author: true, selectable: true %> <div class="card-footer"> - <%= paginate @posts, theme: 'bootstrap-5' %> + <% if @posts.total_pages > 1 %> + <div class="float-end"> + <%= paginate @posts, theme: 'bootstrap-5' %> + </div> + <% end %> + <div class="row align-items-center"> + <div class="col-auto"> + Modifier la sélection + </div> + <div class="col-auto"> + <select name="published" class="form-select"> + <option value="false">Non publiée</option> + <option value="true">Publiée</option> + </select> + </div> + <div class="col-auto"> + <input type="submit" value="Enregistrer" class="btn btn-primary"> + </div> + </div> </div> <% end %> </div> diff --git a/config/locales/communication/fr.yml b/config/locales/communication/fr.yml index 54f6c1d5d4bf97479dd0f5d04abd0e20456364b2..01b3fc28b1eeb5b01e45f83f141b0bd6d056eb8c 100644 --- a/config/locales/communication/fr.yml +++ b/config/locales/communication/fr.yml @@ -302,6 +302,7 @@ fr: title: Équipe pédagogique posts: new_curation: Nouvelle curation + successful_batch_update: Les actualités ont bien été mises à jour see_all: Voir la liste complète (%{number} éléments) enums: communication: diff --git a/config/routes/admin/communication.rb b/config/routes/admin/communication.rb index 4ebcf1ce0531974450775c95d87cadc58b771641..8e3cfeb11a6f02f1bd38a25c432cc4585f7f19e5 100644 --- a/config/routes/admin/communication.rb +++ b/config/routes/admin/communication.rb @@ -25,7 +25,9 @@ namespace :communication do end end resources :authors, controller: 'website/authors', only: [:index, :show] - resources :posts, controller: 'website/posts' + resources :posts, controller: 'website/posts' do + post :publish, on: :collection + end resources :curations, path: 'posts/curations', as: :post_curations, @@ -44,7 +46,7 @@ namespace :communication do end get 'structure' => 'website/structure#edit' patch 'structure' => 'website/structure#update' - + end resources :blocks, controller: 'blocks', except: :index do collection do