From 56ffd2d53d11b74eb0b4748328c4f6696a90ce18 Mon Sep 17 00:00:00 2001
From: Arnaud Levy <arnaud.levy@noesya.coop>
Date: Tue, 17 Dec 2024 09:55:12 +0100
Subject: [PATCH] Vrai nettoyage des ranks (#2505)

* Clean

* children

* fake
---
 .../communication/block/template/contact.rb   | 30 +++++++----
 .../communication/block/with_heading_ranks.rb | 50 ++++++++++++++++---
 app/models/education/program/localization.rb  |  4 ++
 .../communication/blocks/_static.html.erb     |  2 +
 4 files changed, 69 insertions(+), 17 deletions(-)

diff --git a/app/models/communication/block/template/contact.rb b/app/models/communication/block/template/contact.rb
index d256e0a05..7897de683 100644
--- a/app/models/communication/block/template/contact.rb
+++ b/app/models/communication/block/template/contact.rb
@@ -24,15 +24,7 @@ class Communication::Block::Template::Contact < Communication::Block::Template::
 
   has_elements
 
-  def has_emails?
-    emails.any?(&:present?)
-  end
-
-  def has_phone_numbers?
-    phone_numbers.any?(&:present?)
-  end
-
-  def has_socials?
+  def socials
     [
       social_mastodon,
       social_x,
@@ -44,7 +36,25 @@ class Communication::Block::Template::Contact < Communication::Block::Template::
       social_facebook,
       social_tiktok,
       social_github
-    ].any?(&:present?)
+    ].compact_blank
+  end
+
+  # We fake children presence.
+  # This is used by the ranks, so we have ranks.children
+  # https://github.com/osunyorg/admin/pull/2505
+  def children
+    [true]
   end
 
+  def has_emails?
+    emails.any?(&:present?)
+  end
+
+  def has_phone_numbers?
+    phone_numbers.any?(&:present?)
+  end
+
+  def has_socials?
+    socials.any?(&:present?)
+  end
 end
diff --git a/app/models/communication/block/with_heading_ranks.rb b/app/models/communication/block/with_heading_ranks.rb
index 352011031..896865fc3 100644
--- a/app/models/communication/block/with_heading_ranks.rb
+++ b/app/models/communication/block/with_heading_ranks.rb
@@ -1,25 +1,61 @@
 module Communication::Block::WithHeadingRanks
   extend ActiveSupport::Concern
 
-  DEFAULT_HEADING_LEVEL = 2 # h1 is the page title
+  # h1 is the page title
+  DEFAULT_HEADING_LEVEL = 2
 
-  def heading_rank_self
-    title.present? ? heading_rank_base : DEFAULT_HEADING_LEVEL
+  # Title is the block intrinsic title
+  # Not to be confused with `block_title``
+  def heading_self?
+    title.present?
   end
 
-  def heading_rank_children
-    return false unless heading_children?
-    heading_rank_self ? heading_rank_self + 1 : heading_rank_base
+  # Self rank is used for the title (h2 if root, h3 if below a title)
+  def heading_rank_self
+    # No title, no rank self
+    return false unless heading_self?
+    # Otherwise, rank base
+    # Example:
+    # - title h2 (root)
+    # - title h3 (below a title block)
+    heading_rank_base
   end
 
   def heading_children?
     template.children && template.children.any?
   end
 
+  # Rank children is used for the block's children heading
+  def heading_rank_children
+    # If a block has no children, then no rank children
+    return false unless heading_children?
+    # If there's no heading rank self, we take the base rank
+    # Example:
+    # - No title, children h2 (root)
+    # - No title, children h3 (below a title block)
+    return heading_rank_base if heading_rank_self == false
+    # Otherwise, it's the rank self + 1
+    # Example: 
+    # - title h2, children h3 (root)
+    # - title h3, children h4 (below a title block)
+    heading_rank_self + 1
+  end
+
   protected
 
+  # If a block is root, it will have level 2
+  # If a block is below a title block, it will have level 3
+  # Not real yet: if a block is below a subtitle, it will have level 4
+  # There are no subtitles at the moment, so it's all between 2 and 3
   def heading_rank_base
-    block_title.present? ? block_title.heading_rank_self + 1 : DEFAULT_HEADING_LEVEL
+    if block_title.present?
+      # We delegate the rank computing to the block title, and we add 1
+      block_title.heading_rank_self + 1
+    else
+      # If the about has a block base (Education::Program::Localization), we use it
+      # Otherwise, default level (2)
+      about.try(:blocks_heading_rank_base) || DEFAULT_HEADING_LEVEL
+    end
   end
 
   # A block can belong to a title, meaning it is below the title
diff --git a/app/models/education/program/localization.rb b/app/models/education/program/localization.rb
index 6d8e4e4e8..ed1a80320 100644
--- a/app/models/education/program/localization.rb
+++ b/app/models/education/program/localization.rb
@@ -115,6 +115,10 @@ class Education::Program::Localization < ApplicationRecord
     [parent]
   end
 
+  def blocks_heading_rank_base
+    3
+  end
+
   def best_featured_image_source(fallback: true)
     return self if featured_image.attached?
     best_source = parent&.best_featured_image_source(fallback: false)
diff --git a/app/views/admin/communication/blocks/_static.html.erb b/app/views/admin/communication/blocks/_static.html.erb
index a16e67127..d9c9a2a70 100644
--- a/app/views/admin/communication/blocks/_static.html.erb
+++ b/app/views/admin/communication/blocks/_static.html.erb
@@ -9,7 +9,9 @@ should_render_data = block.data && block.data.present?
     slug: >-
       <%= block.slug %>
     ranks:
+<% if block.heading_self? %>
       self: <%= block.heading_rank_self %>
+<% end %>
 <% if block.heading_children? %>
       children: <%= block.heading_rank_children %>
 <% end %>
-- 
GitLab