From dc8446f45f11bf6d3024485d92b31953641f3e9b Mon Sep 17 00:00:00 2001
From: pabois <pierreandre.boissinot@noesya.coop>
Date: Tue, 26 Oct 2021 11:24:54 +0200
Subject: [PATCH] treeview

---
 app/assets/javascripts/admin.js               |  1 +
 app/assets/stylesheets/admin/treeview.sass    | 34 ++++++++++++++++---
 .../communication/website/pages_controller.rb |  8 ++++-
 app/models/communication/website/page.rb      | 16 +++++----
 app/models/concerns/with_tree.rb              | 25 ++++++++++++++
 .../website/pages/_form.html.erb              |  4 ++-
 .../website/pages/_treebranch.html.erb        | 13 ++++---
 .../website/pages/index.html.erb              |  4 +--
 8 files changed, 87 insertions(+), 18 deletions(-)
 create mode 100644 app/models/concerns/with_tree.rb

diff --git a/app/assets/javascripts/admin.js b/app/assets/javascripts/admin.js
index fadf7f47c..bee280c2d 100644
--- a/app/assets/javascripts/admin.js
+++ b/app/assets/javascripts/admin.js
@@ -1,4 +1,5 @@
 //= require activestorage
+//= require bootstrap-sprockets
 //= require jquery3
 //= require jquery_ujs
 //= require notyf/notyf.min
diff --git a/app/assets/stylesheets/admin/treeview.sass b/app/assets/stylesheets/admin/treeview.sass
index 7f2d05042..fa8dfffbf 100644
--- a/app/assets/stylesheets/admin/treeview.sass
+++ b/app/assets/stylesheets/admin/treeview.sass
@@ -6,15 +6,21 @@
         & > .treeview__label
             & > a .close_btn
                 display: none
+                .close_btn--with_children
+                    display: inline
+                .close_btn--without_children
+                    display: none
+
             & > a .open_btn
                 display: inline
+                .open_btn--with_children
+                    display: inline
+                .open_btn--without_children
+                    display: none
+
             & > .move_btn
                 opacity: 0
                 transition: opacity 0.1s
-        &:hover
-            & > .treeview__label
-                & > .move_btn
-                    opacity: 1
 
         & > .treeview__children
             display: none
@@ -33,5 +39,25 @@
                 display: none
 
         &--empty
+            & > .treeview__label
+                & > a .close_btn
+                    .close_btn--with_children
+                        display: none
+                    .close_btn--without_children
+                        display: inline
+
+                & > a .open_btn
+                    .open_btn--with_children
+                        display: none
+                    .open_btn--without_children
+                        display: inline
+
             & > .treeview__children .treeview__empty
                 display: inline
+
+    &--sortable
+        .treeview__element
+            &:hover
+                & > .treeview__label
+                    & > .move_btn
+                        opacity: 1
diff --git a/app/controllers/admin/communication/website/pages_controller.rb b/app/controllers/admin/communication/website/pages_controller.rb
index a08b351fe..3238ed540 100644
--- a/app/controllers/admin/communication/website/pages_controller.rb
+++ b/app/controllers/admin/communication/website/pages_controller.rb
@@ -1,8 +1,10 @@
 class Admin::Communication::Website::PagesController < Admin::Communication::Website::ApplicationController
   load_and_authorize_resource class: Communication::Website::Page
 
+  before_action :get_root_pages, only: [:index, :new, :create, :edit, :update]
+
   def index
-    @pages = @website.pages.root.ordered
+
     breadcrumb
   end
 
@@ -66,6 +68,10 @@ class Admin::Communication::Website::PagesController < Admin::Communication::Web
 
   protected
 
+  def get_root_pages
+    @root_pages = @website.pages.root.ordered
+  end
+
   def breadcrumb
     super
     add_breadcrumb  Communication::Website::Page.model_name.human(count: 2),
diff --git a/app/models/communication/website/page.rb b/app/models/communication/website/page.rb
index 808a6b072..f6f132f8c 100644
--- a/app/models/communication/website/page.rb
+++ b/app/models/communication/website/page.rb
@@ -34,8 +34,9 @@
 #
 
 class Communication::Website::Page < ApplicationRecord
-  include WithSlug
   include WithGithub
+  include WithSlug
+  include WithTree
 
   has_rich_text :text
   has_one_attached_deletable :featured_image
@@ -57,11 +58,6 @@ class Communication::Website::Page < ApplicationRecord
 
   scope :ordered, -> { order(:position) }
   scope :recent, -> { order(updated_at: :desc).limit(5) }
-  scope :root, -> { where(parent_id: nil) }
-
-  def has_children?
-    children.any?
-  end
 
   def github_path_generated
     "_pages/#{path}/index.html".gsub('//', '/')
@@ -75,6 +71,14 @@ class Communication::Website::Page < ApplicationRecord
     )
   end
 
+  def list_of_other_pages
+    pages = []
+    website.pages.where.not(id: id).root.ordered.each do |page|
+      pages.concat(page.self_and_children(0))
+    end
+    pages
+  end
+
   def to_s
     "#{ title }"
   end
diff --git a/app/models/concerns/with_tree.rb b/app/models/concerns/with_tree.rb
new file mode 100644
index 000000000..e45bc999d
--- /dev/null
+++ b/app/models/concerns/with_tree.rb
@@ -0,0 +1,25 @@
+module WithTree
+  extend ActiveSupport::Concern
+
+  included do
+
+    scope :root, -> { where(parent_id: nil) }
+
+    def has_children?
+      children.any?
+    end
+
+    def self_and_children(level)
+      pages = []
+      label = "&nbsp;&nbsp;&nbsp;" * level + self.to_s
+      pages << { label: label, id: self.id }
+      children.each do |child|
+        pages.concat(child.self_and_children(level + 1))
+      end
+      pages
+    end
+
+  end
+
+
+end
diff --git a/app/views/admin/communication/website/pages/_form.html.erb b/app/views/admin/communication/website/pages/_form.html.erb
index d2c2ca65f..b4788412c 100644
--- a/app/views/admin/communication/website/pages/_form.html.erb
+++ b/app/views/admin/communication/website/pages/_form.html.erb
@@ -20,7 +20,9 @@
         <div class="card-body">
           <%= f.input :slug, as: :string %>
           <%= f.input :published %>
-          <%= f.association :parent, collection: page.website.pages.where.not(id: page) %>
+          <%= f.association :parent, collection: page.list_of_other_pages, label_method: ->(p) { sanitize p[:label] }, value_method: ->(p) { p[:id] } %>
+          <ul>
+          </ul>
         </div>
       </div>
       <div class="card flex-fill w-100">
diff --git a/app/views/admin/communication/website/pages/_treebranch.html.erb b/app/views/admin/communication/website/pages/_treebranch.html.erb
index 881d991a0..cad2da67b 100644
--- a/app/views/admin/communication/website/pages/_treebranch.html.erb
+++ b/app/views/admin/communication/website/pages/_treebranch.html.erb
@@ -1,12 +1,17 @@
 <% pages.each do |page| %>
-<%# page.has_children? ? 'treeview__branch js-treeview-branch' : 'treeview__leaf' %>
-  <li class="treeview__element js-treeview-element" data-id="<%= page.id %>" data-parent="<%= page.parent_id %>">
+  <li class="treeview__element js-treeview-element <%= 'treeview__element--empty' unless page.has_children? %>" data-id="<%= page.id %>" data-parent="<%= page.parent_id %>">
     <div class="d-flex align-items-center treeview__label border-bottom p-1">
       <%= link_to children_admin_communication_website_page_path(website_id: page.website.id, id: page.id),
                   class: 'js-treeview-openzone d-inline-block p-2 ps-0', style: 'width: 22px', remote: true do %>
         <% icon_style = page.has_children? ? 'fas' : 'far' %>
-        <span class="open_btn"><i class="<%= icon_style %> fa-folder"></i></span>
-        <span class="close_btn"><i class="<%= icon_style %> fa-folder-open"></i></span>
+        <span class="open_btn">
+          <i class="open_btn--with_children fas fa-folder"></i>
+          <i class="open_btn--without_children far fa-folder"></i>
+        </span>
+        <span class="close_btn">
+          <i class="close_btn--with_children fas fa-folder-open"></i>
+          <i class="close_btn--without_children far fa-folder-open"></i>
+        </span>
       <% end %>
       <%= link_to page, admin_communication_website_page_path(website_id: page.website.id, id: page.id) %>
       <span class="move_btn py-2 ps-2"><i class="fas fa-sort"></i></span>
diff --git a/app/views/admin/communication/website/pages/index.html.erb b/app/views/admin/communication/website/pages/index.html.erb
index f51b6d128..b664f0898 100644
--- a/app/views/admin/communication/website/pages/index.html.erb
+++ b/app/views/admin/communication/website/pages/index.html.erb
@@ -1,7 +1,7 @@
 <% content_for :title, Communication::Website::Page.model_name.human(count: 2) %>
 
-<ul class="list-unstyled treeview js-treeview js-treeview-sortable js-treeview-sortable-container" data-id="" data-sort-url="<%= reorder_admin_communication_website_pages_path %>">
-  <%= render 'treebranch', pages: @pages %>
+<ul class="list-unstyled treeview treeview--sortable js-treeview js-treeview-sortable js-treeview-sortable-container" data-id="" data-sort-url="<%= reorder_admin_communication_website_pages_path %>">
+  <%= render 'treebranch', pages: @root_pages %>
 </ul>
 
 <% content_for :action_bar_right do %>
-- 
GitLab