From 4a53077cd5b4907b44a99685e2e8e227c9d60d68 Mon Sep 17 00:00:00 2001
From: Arnaud Levy <contact@arnaudlevy.com>
Date: Thu, 12 May 2022 10:16:17 +0200
Subject: [PATCH] Fix #375

---
 .../communication/block/template/page.rb      |  36 +++--
 .../blocks/templates/pages/_edit.html.erb     | 144 ++++++++++--------
 .../blocks/templates/pages/_preview.html.erb  |  36 ++---
 .../blocks/templates/pages/_static.html.erb   |   8 +-
 config/locales/communication/en.yml           |   3 +
 config/locales/communication/fr.yml           |   3 +
 6 files changed, 128 insertions(+), 102 deletions(-)

diff --git a/app/models/communication/block/template/page.rb b/app/models/communication/block/template/page.rb
index dd60b571e..fd9d66966 100644
--- a/app/models/communication/block/template/page.rb
+++ b/app/models/communication/block/template/page.rb
@@ -9,33 +9,39 @@ class Communication::Block::Template::Page < Communication::Block::Template
   end
 
   def selected_pages
-    @selected_pages ||= elements.map { |element|
-      p = page(element['id'])
-      next if p.nil?
-      hash_from_page(p, element)
-    }.compact
+    # kind could be: selection (default), children
+    @selected_pages ||= send "selected_pages_#{kind}"
   end
 
   def main_page
     @main_page ||= page(data['page_id'])
   end
 
-  def show_description
-    data['show_description'] || false
+  def show_descriptions
+    data['show_descriptions'] || false
   end
 
-  def show_image
-    data['show_image'] || false
+  def show_images
+    data['show_images'] || false
   end
 
   protected
 
-  def hash_from_page(page, element)
-    {
-      page: page,
-      show_description: element['show_description'] || false,
-      show_image: element['show_image'] || false
-    }.to_dot
+  def kind
+    @kind ||= data['kind'] || 'selection'
+  end
+
+  def selected_pages_selection
+    elements.map { |element|
+      page element['id']
+    }.compact
+  end
+
+  def selected_pages_children
+    return [] unless main_page
+    main_page.children
+             .published
+             .ordered
   end
 
   def page(id)
diff --git a/app/views/admin/communication/blocks/templates/pages/_edit.html.erb b/app/views/admin/communication/blocks/templates/pages/_edit.html.erb
index 9696bd493..8e2989b01 100644
--- a/app/views/admin/communication/blocks/templates/pages/_edit.html.erb
+++ b/app/views/admin/communication/blocks/templates/pages/_edit.html.erb
@@ -1,8 +1,59 @@
 <% pages = collection_tree(@block.about&.website.pages) %>
 
-<h2 class="mt-5">Page principale</h2>
-<div class="row mb-1">
+<div class="row mb-4">
   <div class="col-md-6">
+    <h2 class="h3">Type de liste</h2>
+    <div class="form-check form-check-inline mb-3">
+      <input  class="form-check-input"
+              type="radio"
+              name="kind"
+              v-model="data.kind"
+              value="children"
+              id="kind-children">
+      <label class="form-check-label" for="kind-children">
+        La page principale et ses enfants
+      </label>
+    </div>
+    <div class="form-check form-check-inline">
+      <input  class="form-check-input"
+              type="radio"
+              name="kind"
+              v-model="data.kind"
+              value="selection"
+              id="kind-selection">
+      <label class="form-check-label" for="kind-selection">
+        Une sélection spécifique de pages
+      </label>
+    </div>
+  </div>
+  <div class="col-md-6">
+    <h2 class="h3">Options d'affichage</h2>
+    <div class="form-check">
+      <input  v-model="data.show_description"
+              class="form-check-input boolean optional"
+              id="show_descriptions"
+              type="checkbox">
+      <label  class="form-check-label boolean optional"
+              for="show_descriptions">
+        Afficher les descriptions courtes des pages
+      </label>
+    </div>
+    <div class="form-check">
+      <input  v-model="data.show_image"
+              class="form-check-input boolean optional"
+              id="show_images"
+              type="checkbox">
+      <label  class="form-check-label boolean optional"
+              for="show_images">
+        Afficher les images des pages
+      </label>
+    </div>
+  </div>
+</div>
+
+<div class="row">
+  <div class="col-md-6">
+    <h2 class="h3">Page principale</h2>
     <label class="form-label"
           for="page_id">Sélectionnez une page principale</label>
     <select id="page_id"
@@ -13,69 +64,40 @@
         <option value="<%= page[:id] %>"><%= page[:label].html_safe %></option>
       <% end %>
     </select>
+    <div class="form-text">Cette page principale définira le titre et le lien du bloc. Si vous choisissez une page sans remplir le titre ci-dessus, le titre de la page sera utilisé. Si le titre est rempli, il remplacera le titre de la page sélectionnée, en utilisant le lien de la page.</div>
   </div>
-  <div class="col-md-6">
-    <label class="form-label">Option d'affichage</label>
-    <div class="form-check">
-      <input v-model="data.show_description" class="form-check-input boolean optional" id="show_description" type="checkbox">
-      <label class="form-check-label boolean optional"
-            for="show_description">Afficher la description courte</label>
-    </div>
-    <div class="form-check">
-      <input v-model="data.show_image" class="form-check-input boolean optional" :id="'show_image'" type="checkbox">
-      <label class="form-check-label boolean optional"
-            :for="'show_image'">Afficher l'image</label>
-    </div>
-  </div>
-  <div v-if="!data.category_id" class="col-md-12 mt-5">
-    <h2>Ajouter des pages</h2>
-    <a  class="<%= button_classes('mb-4') %>"
+  <div class="col-md-6" v-if="data.kind == 'selection'">
+    <h2 class="h3">Pages sélectionnées</h2>
+    <a  class="<%= button_classes('mb-3') %>"
         v-on:click="data.elements.push({id: ''})">
         <%= t '.add_page' %>
     </a>
-    <draggable :list="data.elements" handle=".dragHandle">
-      <div v-for="(page, index) in data.elements">
-        <div class="card">
-          <div class="card-body">
-            <div class="row">
-              <div class="mb-3">
-                <a  class="btn btn-sm btn-danger float-end"
-                    v-on:click="data.elements.splice(data.elements.indexOf(page), 1)"
-                    title="Delete">
-                    <i class="fas fa-times"></i>
-                </a>
-                <a class="btn ps-0 pt-0 dragHandle" title="Drag and drop">
-                  <i class="fa fa-bars handle"></i>
-                </a>
-              </div>
-              <div class="col-6">
-                <label  class="form-label"
-                        :for="'page-' + index + '-name'">Page secondaire</label>
-                <select :id="'page-' + index + '-name'"
-                        class="form-select select"
-                        v-model="page.id">
-                  <option value="" disabled>Aucune page</option>
-                  <% pages.each_with_index do |page, index| %>
-                    <option value="<%= page[:id] %>"><%= page[:label].html_safe %></option>
-                  <% end %>
-                </select>
-              </div>
-              <div class="col-6">
-                <div class="col-md-6">
-                  <label class="form-label">Options d'affichage</label>
-                  <div class="form-check">
-                    <input v-model="page.show_description" class="form-check-input boolean optional" :id="'page-' + index + '-show_short_description'" type="checkbox">
-                    <label class="form-check-label boolean optional"
-                          :for="'page-' + index + '-show_short_description'">Afficher la description courte</label>
-                  </div>
-                  <div class="form-check">
-                    <input v-model="page.show_image" class="form-check-input boolean optional" :id="'page-' + index + '-show_image'" type="checkbox">
-                    <label class="form-check-label boolean optional"
-                          :for="'page-' + index + '-show_image'">Afficher l'image</label>
-                  </div>
-                </div>
-              </div>
-            </div>
+    <draggable :list="data.elements" handle=".dragHandle" class="list-group">
+      <div v-for="(page, index) in data.elements" class="list-group-item">
+        <div class="d-flex">
+          <div>
+            <a class="btn ps-0 pt-0 dragHandle" title="Drag and drop">
+              <i class="fa fa-bars handle"></i>
+            </a>
+          </div>
+          <div class="flex-fill">
+            <label  class="form-label d-none"
+                    :for="'page-' + index + '-name'">Page</label>
+            <select :id="'page-' + index + '-name'"
+                    class="form-select select"
+                    v-model="page.id">
+              <option value="" disabled>Aucune page</option>
+              <% pages.each_with_index do |page, index| %>
+                <option value="<%= page[:id] %>"><%= page[:label].html_safe %></option>
+              <% end %>
+            </select>
+          </div>
+          <div>
+            <a  class="btn btn-sm btn-danger ms-3"
+                v-on:click="data.elements.splice(data.elements.indexOf(page), 1)"
+                title="Supprimer">
+                <i class="fas fa-times"></i>
+            </a>
           </div>
         </div>
       </div>
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 2175cc87a..15a464e31 100644
--- a/app/views/admin/communication/blocks/templates/pages/_preview.html.erb
+++ b/app/views/admin/communication/blocks/templates/pages/_preview.html.erb
@@ -1,27 +1,21 @@
 <% if @block.data %>
   <% if @block.template.main_page %>
-    <h2 class="mb-4"><%= @block.template.main_page.slug %></h2>
+    <h2 class="h5 mb-4"><%= @block.template.main_page.slug %></h2>
   <% end %>
-  <% if @block.template.selected_pages.any? %>
-    <div class="<%= 'row' unless @preview %>">
-      <% @block.template.selected_pages.each do |element| %>
-        <div class="<%= 'col-md-4' unless @preview %>">
-          <div class="card">
-            <div class="card-header">
-              <h3 class="card-title h5"><%= element.page %></h3>
-            </div>
-            <div class="card-body">
-              <div class="mb-3">
-                <% if element.show_image %>
-                  <%= kamifusen_tag element.page.featured_image,
-                                    class: 'img-fluid' if element.page.featured_image.attached? && element.page.featured_image.variable? %>
-                <% end %>
-              </div>
-              <p><%= element.page.description_short if element.show_description %></p>
-            </div>
-          </div>
-        </div>
-      <% end %>
+  <% @block.template.selected_pages.each do |element| %>
+    <div class="card mb-4">
+      <div class="card-header">
+        <h3 class="card-title h5"><%= element %></h3>
+      </div>
+      <div class="card-body">
+        <% if @block.template.show_images && element.page.featured_image.attached? %>
+          <%= kamifusen_tag element.featured_image,
+                            class: 'img-fluid mb-3' %>
+        <% end %>
+        <% if @block.template.show_descriptions %>
+          <p><%= element.page.description_short %></p>
+        <% end %>
+      </div>
     </div>
   <% end %>
 <% end %>
diff --git a/app/views/admin/communication/blocks/templates/pages/_static.html.erb b/app/views/admin/communication/blocks/templates/pages/_static.html.erb
index 1790aede1..87788b6ac 100644
--- a/app/views/admin/communication/blocks/templates/pages/_static.html.erb
+++ b/app/views/admin/communication/blocks/templates/pages/_static.html.erb
@@ -1,11 +1,9 @@
 <% if block.template.main_page %>
       page: <%= block.template.main_page.generated_path %>
-      show_description: <%= block.template.show_description %>
-      show_image: <%= block.template.show_image %>
 <% end %>
+      show_descriptions: <%= block.template.show_descriptions %>
+      show_images: <%= block.template.show_images %>
       pages:
 <% block.template.selected_pages.each do |element| %>
-        - slug: <%= element.page.generated_path %>
-          show_description: <%= element.show_description %>
-          show_image: <%= element.show_image %>
+        - <%= element.generated_path %>
 <% end %>
diff --git a/config/locales/communication/en.yml b/config/locales/communication/en.yml
index 0688acbd3..92968cd7c 100644
--- a/config/locales/communication/en.yml
+++ b/config/locales/communication/en.yml
@@ -178,6 +178,9 @@ en:
               role_placeholder: Enter person's role
               drag_title: Drag and drop to organize persons
               delete_title: Remove person
+          pages:
+            edit:
+              add_page: Select a page
           partners:
             edit:
               add_partner: Add partner
diff --git a/config/locales/communication/fr.yml b/config/locales/communication/fr.yml
index 61c9a5724..48feb27ed 100644
--- a/config/locales/communication/fr.yml
+++ b/config/locales/communication/fr.yml
@@ -162,6 +162,9 @@ fr:
               role_placeholder: Indiquer le rôle de la personne
               drag_title: Glisser-déposer pour organiser les personnes
               delete_title: Enlever la personne
+          pages:
+            edit:
+              add_page: Sélectionner une page
           partners:
             edit:
               add_partner: Ajouter un partenaire
-- 
GitLab