From 663f4ba4dd564c7d5928aa4fc17be3a049e74c7e Mon Sep 17 00:00:00 2001
From: Arnaud Levy <contact@arnaudlevy.com>
Date: Fri, 17 Jun 2022 17:48:35 +0200
Subject: [PATCH] partners

---
 .../block/component/organization.rb           |  7 ++
 .../communication/block/template/page.rb      | 20 ++---
 .../block/template/page/element.rb            |  3 +
 .../communication/block/template/partner.rb   | 84 ++++++++++---------
 .../block/template/partner/element.rb         | 24 ++++++
 .../components/organization/_edit.html.erb    | 21 +++++
 .../components/organization/_preview.html.erb |  1 +
 .../components/organization/_static.html.erb  |  1 +
 .../blocks/templates/partners/_edit.html.erb  | 61 ++------------
 .../templates/partners/_preview.html.erb      | 24 +++---
 .../templates/partners/_static.html.erb       | 19 ++---
 config/locales/communication/fr.yml           | 21 +++--
 12 files changed, 150 insertions(+), 136 deletions(-)
 create mode 100644 app/models/communication/block/component/organization.rb
 create mode 100644 app/models/communication/block/template/page/element.rb
 create mode 100644 app/models/communication/block/template/partner/element.rb
 create mode 100644 app/views/admin/communication/blocks/components/organization/_edit.html.erb
 create mode 100644 app/views/admin/communication/blocks/components/organization/_preview.html.erb
 create mode 100644 app/views/admin/communication/blocks/components/organization/_static.html.erb

diff --git a/app/models/communication/block/component/organization.rb b/app/models/communication/block/component/organization.rb
new file mode 100644
index 000000000..f92062893
--- /dev/null
+++ b/app/models/communication/block/component/organization.rb
@@ -0,0 +1,7 @@
+class Communication::Block::Component::Organization < Communication::Block::Component::Base
+
+  def organization
+    template.block.university.organizations.find_by(id: data)
+  end
+
+end
diff --git a/app/models/communication/block/template/page.rb b/app/models/communication/block/template/page.rb
index c0bfa1ac6..578ad8a65 100644
--- a/app/models/communication/block/template/page.rb
+++ b/app/models/communication/block/template/page.rb
@@ -1,19 +1,12 @@
 class Communication::Block::Template::Page < Communication::Block::Template::Base
 
   has_layouts [:grid, :list, :cards]
+  has_elements Communication::Block::Template::Page::Element
+  has_component :mode, :option, options: [:selection, :children]
   has_component :text, :rich_text
 
-  def build_git_dependencies
-    add_dependency main_page
-    selected_pages.each do |page|
-      add_dependency page
-      add_dependency page.active_storage_blobs
-    end
-  end
-
   def selected_pages
-    # kind could be: selection (default), children
-    @selected_pages ||= send "selected_pages_#{kind}"
+    @selected_pages ||= send "selected_pages_#{mode}"
   end
 
   def main_page
@@ -34,13 +27,10 @@ class Communication::Block::Template::Page < Communication::Block::Template::Bas
 
   protected
 
-  def kind
-    @kind ||= data['kind'] || 'selection'
-  end
-
   def selected_pages_selection
+    return []
     elements.map { |element|
-      page element['id']
+      element.page
     }.compact
   end
 
diff --git a/app/models/communication/block/template/page/element.rb b/app/models/communication/block/template/page/element.rb
new file mode 100644
index 000000000..c785d9d93
--- /dev/null
+++ b/app/models/communication/block/template/page/element.rb
@@ -0,0 +1,3 @@
+class Communication::Block::Template::Page::Element < Communication::Block::Template::Base
+
+end
diff --git a/app/models/communication/block/template/partner.rb b/app/models/communication/block/template/partner.rb
index 4a19277ae..6d3b2d286 100644
--- a/app/models/communication/block/template/partner.rb
+++ b/app/models/communication/block/template/partner.rb
@@ -1,47 +1,51 @@
 class Communication::Block::Template::Partner < Communication::Block::Template::Base
-  def build_git_dependencies
-    add_dependency active_storage_blobs
-    add_dependency organizations
-    organizations.each do |organization|
-      add_dependency organization.active_storage_blobs
-    end
-  end
 
-  def partners
-    @partners ||= elements.map { |element|
-      partner(element)
-    }.compact
-  end
+  has_elements Communication::Block::Template::Partner::Element
 
-  def active_storage_blobs
-    @active_storage_blobs ||= partners.map { |partner|
-      partner.blob
-    }.compact
-  end
 
-  protected
+  # def build_git_dependencies
+  #   add_dependency active_storage_blobs
+  #   add_dependency organizations
+  #   organizations.each do |organization|
+  #     add_dependency organization.active_storage_blobs
+  #   end
+  # end
+  #
+  # def partners
+  #   @partners ||= elements.map { |element|
+  #     partner(element)
+  #   }.compact
+  # end
 
-  def organizations
-    @organizations ||= partners.map { |partner|
-      partner.organization
-    }.compact
-  end
+  # def active_storage_blobs
+  #   @active_storage_blobs ||= partners.map { |partner|
+  #     partner.blob
+  #   }.compact
+  # end
 
-  def partner(element)
-    # Init to have easy tests in the views and dependencies
-    element['organization'] = nil
-    element['blob'] = nil
-    if element['id']
-      organization = university.organizations.find_by id: element['id']
-      if organization
-        element['organization'] = organization
-        element['name'] = organization.to_s
-        element['url'] = organization.url
-        element['blob'] = organization.logo&.blob
-      end
-    else
-      element['blob'] = find_blob element, 'logo'
-    end
-    element.to_dot
-  end
+  # protected
+
+  # def organizations
+  #   @organizations ||= partners.map { |partner|
+  #     partner.organization
+  #   }.compact
+  # end
+  #
+  # def partner(element)
+  #   # Init to have easy tests in the views and dependencies
+  #   element['organization'] = nil
+  #   element['blob'] = nil
+  #   if element['id']
+  #     organization = university.organizations.find_by id: element['id']
+  #     if organization
+  #       element['organization'] = organization
+  #       element['name'] = organization.to_s
+  #       element['url'] = organization.url
+  #       element['blob'] = organization.logo&.blob
+  #     end
+  #   else
+  #     element['blob'] = find_blob element, 'logo'
+  #   end
+  #   element.to_dot
+  # end
 end
diff --git a/app/models/communication/block/template/partner/element.rb b/app/models/communication/block/template/partner/element.rb
new file mode 100644
index 000000000..1c9b6009a
--- /dev/null
+++ b/app/models/communication/block/template/partner/element.rb
@@ -0,0 +1,24 @@
+class Communication::Block::Template::Partner::Element < Communication::Block::Template::Base
+
+  has_component :id, :organization
+  has_component :name, :string
+  has_component :url, :string
+  has_component :logo, :image
+
+  def organization
+    id_component.organization
+  end
+
+  def best_name
+    organization ? organization.name : name
+  end
+
+  def best_url
+    organization ? organization.url : url
+  end
+
+  def best_logo
+    organization ? organization.logo.blob : logo_component.blob
+  end
+
+end
diff --git a/app/views/admin/communication/blocks/components/organization/_edit.html.erb b/app/views/admin/communication/blocks/components/organization/_edit.html.erb
new file mode 100644
index 000000000..5657ea94d
--- /dev/null
+++ b/app/views/admin/communication/blocks/components/organization/_edit.html.erb
@@ -0,0 +1,21 @@
+<%
+organizations = current_university.organizations.ordered
+%>
+<% unless label.blank? %>
+  <label  class="form-label"
+          :for="<%= dom_id.html_safe %>">
+    <%= label %>
+  </label>
+<% end %>
+<select :id="<%= dom_id.html_safe %>"
+        class="form-select select mb-3"
+        v-model="<%= model %>.<%= property %>">
+  <option value="" :selected="true">
+    <%= t "#{i18n_component}.unregistered" %>
+  </option>
+  <% organizations.each do |organization| %>
+    <option value="<%= organization.id %>">
+      <%= organization.name %>
+    </option>
+  <% end %>
+</select>
diff --git a/app/views/admin/communication/blocks/components/organization/_preview.html.erb b/app/views/admin/communication/blocks/components/organization/_preview.html.erb
new file mode 100644
index 000000000..e303dbb1e
--- /dev/null
+++ b/app/views/admin/communication/blocks/components/organization/_preview.html.erb
@@ -0,0 +1 @@
+<%= component.organization.to_s %>
diff --git a/app/views/admin/communication/blocks/components/organization/_static.html.erb b/app/views/admin/communication/blocks/components/organization/_static.html.erb
new file mode 100644
index 000000000..a871dde97
--- /dev/null
+++ b/app/views/admin/communication/blocks/components/organization/_static.html.erb
@@ -0,0 +1 @@
+<%= indentation %><%= '- ' if list %><%= property %>: <%= value %>
diff --git a/app/views/admin/communication/blocks/templates/partners/_edit.html.erb b/app/views/admin/communication/blocks/templates/partners/_edit.html.erb
index cd3b51853..1492348dc 100644
--- a/app/views/admin/communication/blocks/templates/partners/_edit.html.erb
+++ b/app/views/admin/communication/blocks/templates/partners/_edit.html.erb
@@ -1,9 +1,6 @@
-<a  class="<%= button_classes('mb-4 me-1') %>"
-    v-on:click="data.elements.push({id:'', name: '', url: '', logo: {}})">
-    <%= t '.add_partner' %>
-</a>
+<%= block_component_add_element t('.add_partner') %>
 <draggable :list="data.elements" class="list-group" handle=".partnerHandle">
-  <div v-for="(partner, index) in data.elements" class="list-group-item">
+  <div v-for="(element, index) in data.elements" class="list-group-item">
     <div class="d-flex">
       <div>
         <a class="btn ps-0 pt-0 partnerHandle">
@@ -13,62 +10,18 @@
       <div class="flex-fill">
         <div class="row">
          <div class="col-lg-4">
-            <select :id="'organization-' + index + '-id'"
-                    class="form-select select"
-                    v-model="partner.id">
-              <option value="" :selected="true"><%= t '.unregistered_organization' %></option>
-              <% current_university.organizations.ordered.each_with_index do |organization, index| %>
-                <option value="<%= organization.id %>"><%= organization.name %></option>
-              <% end %>
-            </select>
+           <%= block_component_edit :id, template: @element, label: '' %>
           </div>
         </div>
-        <div class="row mt-3"  v-if="!partner.id">
+        <div class="row"  v-if="!element.id">
           <div class="col-lg-4">
-            <label  class="form-label"
-                    :for="'partner-' + index + '-name'"><%= t '.partner_name_label' %></label>
-
-            <input class="form-control mb-3"
-                  type="text"
-                  v-model="partner.name"
-                  placeholder="<%= t '.partner_name_placeholder' %>"
-                  :id="'partner-' + index + '-name'">
+            <%= block_component_edit :name, template: @element %>
           </div>
           <div class="col-lg-4">
-            <label  class="form-label"
-                    :for="'partner-' + index + '-url'">
-              <%= t '.partner_url_label' %>
-            </label>
-            <input class="form-control mb-3"
-                  type="url"
-                  v-model="partner.url"
-                  placeholder="<%= t '.partner_url_placeholder' %>"
-                  :id="'partner-' + index + '-url'">
+            <%= block_component_edit :url, template: @element %>
           </div>
           <div class="col-lg-4">
-            <div v-if="!partner.logo.id">
-              <%# TODO : create a uploader vue3 component %>
-              <label  class="form-label"
-                      :for="'partner-' + index + '-logo'">
-                <%= t '.partner_logo_label' %>
-              </label>
-              <input  class="form-control mb-3"
-                      type="file"
-                      accept="image/*"
-                      @change="onFileImageChange( $event, partner, 'logo' )"
-                      :id="'partner-' + index + '-logo'">
-            </div>
-            <div v-if="partner.logo.id">
-              <img :src="getImageUrl(partner.logo)"
-                    class="img-fluid"
-                    style="max-height: 80px"
-                    />
-              <a  class="btn btn-sm btn-danger ms-2"
-                  v-on:click="partner.logo={}">
-                  <i class="fas fa-times"></i>
-                  <%= t '.remove_logo' %>
-              </a>
-            </div>
+            <%= block_component_edit :logo, template: @element %>
           </div>
         </div>
       </div>
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 989a14a51..0498531d1 100644
--- a/app/views/admin/communication/blocks/templates/partners/_preview.html.erb
+++ b/app/views/admin/communication/blocks/templates/partners/_preview.html.erb
@@ -1,11 +1,15 @@
-<% @block.template.partners.each do |partner| %>
-  <article class="card">
-    <%= kamifusen_tag partner.blob,
-                      width: 300,
-                      class: 'img-fluid mb-3' unless partner.blob.nil? %>
-    <div class="card-body">
-      <h3 class="card-title h5"><%= partner.name %></h3>
-      <p class="mb-0"><%= partner.url %></p>
+<div class="row">
+  <% @block.template.elements.each do |element| %>
+    <div class="col-6 mb-3">
+      <%= kamifusen_tag element.best_logo,
+                        width: 600,
+                        class: 'img-fluid mb-2' unless element.best_logo.nil? %>
+      <p>
+        <%= element.best_name %><br>
+        <span class="small">
+          <%= element.best_url %>
+        </span>
+      </p>
     </div>
-  </article>
-<% end %>
+  <% end %>
+</div>
diff --git a/app/views/admin/communication/blocks/templates/partners/_static.html.erb b/app/views/admin/communication/blocks/templates/partners/_static.html.erb
index c9b315917..8785dd573 100644
--- a/app/views/admin/communication/blocks/templates/partners/_static.html.erb
+++ b/app/views/admin/communication/blocks/templates/partners/_static.html.erb
@@ -1,11 +1,10 @@
-<% block.template.partners.each do |partner|
-      if partner.organization %>
-      - slug: "<%= partner.organization.slug %>"
-      <% else %>
-      - name: >
-          <%= prepare_text_for_static partner['name'], 5 %>
-        url: >-
-          <%= prepare_text_for_static partner['url'], 5 %>
-        logo: "<%= partner.blob&.id %>"
-      <% end %>
+<%
+block.template.elements.each do |element| %>
+<% if element.organization %>
+      - slug: "<%= element.organization.slug %>"
+<% else %>
+<%= block_component_static :name, template: element, list: true %>
+<%= block_component_static :url, template: element, depth: 4 %>
+        logo: "<%= element.logo_component.blob&.id %>"
+<% end %>
 <% end %>
diff --git a/config/locales/communication/fr.yml b/config/locales/communication/fr.yml
index 30aa26e4f..f3800e9af 100644
--- a/config/locales/communication/fr.yml
+++ b/config/locales/communication/fr.yml
@@ -320,13 +320,20 @@ fr:
             description: Une liste de partenaires, avec leur logo, leur site et leur nom.
             edit:
               add_partner: Ajouter un partenaire
-              partner_name_label: Partenaire
-              partner_name_placeholder: Entrer le nom du partenaire
-              partner_url_label: Site Web
-              partner_url_placeholder: https://
-              partner_logo_label: Logo
-              remove_logo: Enlever le logo
-              remove_partner: Enlever le partenaire
+              element:
+                id:
+                  label: Organisation
+                  placeholder: Choisir l'organisation
+                  unregistered: Organisation non enregistrée
+                name:
+                  label: Nom
+                  placeholder: Entrer le nom du partenaire
+                url:
+                  label: Site Web
+                  placeholder: https://
+                logo_label: Logo
+                remove_logo: Enlever le logo
+                remove_partner: Enlever le partenaire
           posts:
             description: Une liste d'actualités mises en avant.
             edit:
-- 
GitLab