From b3f0ffeb7dcd28c67ab0558ccc0eb557608705c1 Mon Sep 17 00:00:00 2001
From: Arnaud Levy <contact@arnaudlevy.com>
Date: Mon, 25 Apr 2022 17:34:55 +0200
Subject: [PATCH] facets wip

---
 Gemfile                                       | 46 +++++++++++--------
 Gemfile.lock                                  |  6 +++
 .../extranet/persons_controller.rb            | 10 +++-
 app/models/university/person.rb               |  7 ++-
 app/models/university/person/administrator.rb |  1 +
 app/models/university/person/alumnus.rb       |  1 +
 .../university/person/alumnus/facets.rb       | 18 ++++++++
 app/models/university/person/author.rb        |  1 +
 app/models/university/person/researcher.rb    |  1 +
 app/models/university/person/teacher.rb       |  1 +
 app/views/extranet/persons/_list.html.erb     | 14 +-----
 app/views/extranet/persons/_person.html.erb   | 11 +++++
 app/views/extranet/persons/index.html.erb     | 21 +++++++--
 ...25152944_add_name_to_university_persons.rb |  5 ++
 db/schema.rb                                  | 20 +++++++-
 15 files changed, 124 insertions(+), 39 deletions(-)
 create mode 100644 app/models/university/person/alumnus/facets.rb
 create mode 100644 app/views/extranet/persons/_person.html.erb
 create mode 100644 db/migrate/20220425152944_add_name_to_university_persons.rb

diff --git a/Gemfile b/Gemfile
index b2bea4e6b..e9a3e9d08 100644
--- a/Gemfile
+++ b/Gemfile
@@ -3,49 +3,55 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" }
 
 ruby '2.7.5'
 
-gem 'angularjs-rails'
+# Infrastructure
 gem 'aws-sdk-s3'
+gem 'bugsnag'
+gem 'gitlab'
+gem 'image_processing'
+gem 'mini_magick'
+gem 'octokit'
+gem 'pg', '~> 1.1'
+gem 'puma'
+
+# Back-end
+gem 'cancancan'
 gem 'bootsnap', '>= 1.4.4', require: false
+gem 'curation'#, path: '../../arnaudlevy/curation'
+gem 'delayed_job_active_record'
+gem 'delayed_job_web'
+gem 'faceted_search'
+gem 'has_scope', '~> 0.8.0'
+gem 'hash_dot'
+gem 'rails', '~> 6.1'
+gem 'rails-i18n'
+gem 'sanitize'
+gem 'sib-api-v3-sdk'
+gem 'two_factor_authentication', git: 'https://github.com/noesya/two_factor_authentication.git'
+# gem 'two_factor_authentication', path: '../two_factor_authentication'
+
+# Front-end
+gem 'angularjs-rails'
 gem 'bootstrap'
 gem 'bootstrap5-kaminari-views'
 gem 'breadcrumbs_on_rails'
-gem 'bugsnag'
-gem 'cancancan'
 gem 'cocoon', '~> 1.2'
 gem 'country_select'
-gem 'curation'#, path: '../../arnaudlevy/curation'
-gem 'delayed_job_active_record'
-gem 'delayed_job_web'
 gem 'devise'
 gem 'devise-i18n'
 gem 'enum_help'
 gem 'front_matter_parser'
 gem 'gdpr'
-gem 'gitlab'
-gem 'has_scope', '~> 0.8.0'
-gem 'hash_dot'
-gem 'image_processing'
 gem 'jbuilder'
 gem 'jquery-rails'
 gem 'kamifusen'#, path: '../kamifusen'
 gem 'kaminari'
-gem 'mini_magick'
-gem 'octokit'
-gem 'pg', '~> 1.1'
-gem 'puma'
-gem 'rails', '~> 6.1'
-gem 'rails-i18n'
-gem 'sanitize'
 gem 'sassc-rails'
-gem 'sib-api-v3-sdk'
 gem 'simple_form'
 gem 'simple_form_bs5_file_input'#, path: '../simple_form_bs5_file_input'
 gem 'simple_form_password_with_hints'#, path: '../simple_form_password_with_hints'
 gem 'simple-navigation'
 gem 'summernote-rails', git: 'https://github.com/noesya/summernote-rails.git', branch: 'activestorage'
 # gem 'summernote-rails', path: '../summernote-rails'
-gem 'two_factor_authentication', git: 'https://github.com/noesya/two_factor_authentication.git'
-# gem 'two_factor_authentication', path: '../two_factor_authentication'
 
 group :development, :test do
   gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
diff --git a/Gemfile.lock b/Gemfile.lock
index a1cbe2c60..7c67efbad 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -172,6 +172,9 @@ GEM
     ethon (0.15.0)
       ffi (>= 1.15.0)
     execjs (2.8.1)
+    faceted_search (3.5.11)
+      font-awesome-sass
+      rails (>= 5.2.0, < 7)
     faraday (1.10.0)
       faraday-em_http (~> 1.0)
       faraday-em_synchrony (~> 1.0)
@@ -208,6 +211,8 @@ GEM
     ffi (1.15.5)
     figaro (1.2.0)
       thor (>= 0.14.0, < 2)
+    font-awesome-sass (6.1.1)
+      sassc (~> 2.0)
     front_matter_parser (1.0.1)
     gdpr (1.2.3)
       js_cookie_rails
@@ -469,6 +474,7 @@ DEPENDENCIES
   devise
   devise-i18n
   enum_help
+  faceted_search
   figaro
   front_matter_parser
   gdpr
diff --git a/app/controllers/extranet/persons_controller.rb b/app/controllers/extranet/persons_controller.rb
index 172fc4473..977822b95 100644
--- a/app/controllers/extranet/persons_controller.rb
+++ b/app/controllers/extranet/persons_controller.rb
@@ -4,7 +4,15 @@ class Extranet::PersonsController < Extranet::ApplicationController
                               through_association: :people
 
   def index
-    @people = current_extranet.about&.alumni || @people.alumni
+    alumni = current_extranet.about&.alumni || @people.alumni
+    @facets = University::Person::Alumnus::Facets.new params[:facets], {
+      model: alumni,
+      about: current_extranet.about
+    }
+    @people = @facets.results
+                     .ordered
+                     .page params[:page]
+    @count = @people.total_count
     breadcrumb
   end
 
diff --git a/app/models/university/person.rb b/app/models/university/person.rb
index 5020468f0..8f4533ab0 100644
--- a/app/models/university/person.rb
+++ b/app/models/university/person.rb
@@ -15,6 +15,7 @@
 #  is_teacher        :boolean
 #  last_name         :string
 #  linkedin          :string
+#  name              :string
 #  phone             :string
 #  slug              :string
 #  tenure            :boolean          default(FALSE)
@@ -101,7 +102,7 @@ class University::Person < ApplicationRecord
                           allow_blank: true,
                           if: :will_save_change_to_email?
 
-  before_validation :sanitize_email
+  before_validation :sanitize_email, :prepare_name
 
   scope :ordered,         -> { order(:last_name, :first_name) }
   scope :administration,  -> { where(is_administration: true) }
@@ -183,4 +184,8 @@ class University::Person < ApplicationRecord
   def sanitize_email
     self.email = self.email.to_s.downcase.strip
   end
+
+  def prepare_name
+    self.name = to_s
+  end
 end
diff --git a/app/models/university/person/administrator.rb b/app/models/university/person/administrator.rb
index f5fda080a..da5cbf553 100644
--- a/app/models/university/person/administrator.rb
+++ b/app/models/university/person/administrator.rb
@@ -15,6 +15,7 @@
 #  is_teacher        :boolean
 #  last_name         :string
 #  linkedin          :string
+#  name              :string
 #  phone             :string
 #  slug              :string
 #  tenure            :boolean          default(FALSE)
diff --git a/app/models/university/person/alumnus.rb b/app/models/university/person/alumnus.rb
index 06c70f24c..f9a0ae78d 100644
--- a/app/models/university/person/alumnus.rb
+++ b/app/models/university/person/alumnus.rb
@@ -15,6 +15,7 @@
 #  is_teacher        :boolean
 #  last_name         :string
 #  linkedin          :string
+#  name              :string
 #  phone             :string
 #  slug              :string
 #  tenure            :boolean          default(FALSE)
diff --git a/app/models/university/person/alumnus/facets.rb b/app/models/university/person/alumnus/facets.rb
new file mode 100644
index 000000000..5cc231c58
--- /dev/null
+++ b/app/models/university/person/alumnus/facets.rb
@@ -0,0 +1,18 @@
+class University::Person::Alumnus::Facets < FacetedSearch::Facets
+  def initialize(params, options)
+    super params
+
+    @model = options[:model]
+    @about = options[:about]
+
+    filter_with_text :name
+
+    # TODO année de diplôme
+
+    # TODO liste des formations (si about ≠ formation)
+    # filter_with_list :program, {
+    #   source: @about.programs,
+    #   habtm: true
+    # }
+  end
+end
diff --git a/app/models/university/person/author.rb b/app/models/university/person/author.rb
index 67dda6a6e..95faae1d6 100644
--- a/app/models/university/person/author.rb
+++ b/app/models/university/person/author.rb
@@ -15,6 +15,7 @@
 #  is_teacher        :boolean
 #  last_name         :string
 #  linkedin          :string
+#  name              :string
 #  phone             :string
 #  slug              :string
 #  tenure            :boolean          default(FALSE)
diff --git a/app/models/university/person/researcher.rb b/app/models/university/person/researcher.rb
index 8fffe668f..079783999 100644
--- a/app/models/university/person/researcher.rb
+++ b/app/models/university/person/researcher.rb
@@ -15,6 +15,7 @@
 #  is_teacher        :boolean
 #  last_name         :string
 #  linkedin          :string
+#  name              :string
 #  phone             :string
 #  slug              :string
 #  tenure            :boolean          default(FALSE)
diff --git a/app/models/university/person/teacher.rb b/app/models/university/person/teacher.rb
index df1e88803..4f4243116 100644
--- a/app/models/university/person/teacher.rb
+++ b/app/models/university/person/teacher.rb
@@ -15,6 +15,7 @@
 #  is_teacher        :boolean
 #  last_name         :string
 #  linkedin          :string
+#  name              :string
 #  phone             :string
 #  slug              :string
 #  tenure            :boolean          default(FALSE)
diff --git a/app/views/extranet/persons/_list.html.erb b/app/views/extranet/persons/_list.html.erb
index 7922cd391..064c37033 100644
--- a/app/views/extranet/persons/_list.html.erb
+++ b/app/views/extranet/persons/_list.html.erb
@@ -2,19 +2,7 @@
 <div class="row">
   <% people_paged.each do |person| %>
     <div class="col-xxl-2 col-md-3">
-      <article class="mb-4 position-relative">
-        <% if person.picture.attached? %>
-          <%= kamifusen_tag person.picture, width: 400, class: 'img-fluid' %>
-        <% else %>
-          <%= image_tag 'extranet/avatar.png', width: 400, class: 'img-fluid' %>
-        <% end %>
-        <%= link_to person, class: 'stretched-link' do %>
-          <%= person.first_name %>
-          <b>
-            <%= person.last_name %>
-          </b>
-        <% end %>
-      </article>
+      <%= render 'extranet/persons/person', person: person %>
     </div>
   <% end %>
 </div>
diff --git a/app/views/extranet/persons/_person.html.erb b/app/views/extranet/persons/_person.html.erb
new file mode 100644
index 000000000..f8151bdac
--- /dev/null
+++ b/app/views/extranet/persons/_person.html.erb
@@ -0,0 +1,11 @@
+<article class="mb-4 position-relative">
+  <% if person.picture.attached? %>
+    <%= kamifusen_tag person.picture, width: 400, class: 'img-fluid' %>
+  <% else %>
+    <%= image_tag 'extranet/avatar.png', width: 400, class: 'img-fluid' %>
+  <% end %>
+  <%= link_to person, class: 'stretched-link' do %>
+    <%= person.first_name %>
+    <b><%= person.last_name %></b>
+  <% end %>
+</article>
diff --git a/app/views/extranet/persons/index.html.erb b/app/views/extranet/persons/index.html.erb
index f12ba9132..11b59fcc0 100644
--- a/app/views/extranet/persons/index.html.erb
+++ b/app/views/extranet/persons/index.html.erb
@@ -7,11 +7,26 @@
     </div>
     <div class="col-md-3 text-end">
       <p>
-        <%= @people.count %>
-        <%= University::Person::Alumnus.model_name.human(count: @people.count).downcase %>
+        <%= @count %>
+        <%= University::Person::Alumnus.model_name.human(count: @count).downcase %>
       </p>
     </div>
   </div>
 </header>
 
-<%= render 'extranet/persons/list', people: @people %>
+<div class="row">
+  <div class="col-lg-3">
+    <%= render 'faceted_search/facets', facets: @facets %>
+  </div>
+  <div class="offset-lg-1 col-lg-8">
+    <div class="row">
+      <% @people.each do |person| %>
+        <div class="col-xxl-3 col-md-4 col-sm-6">
+          <%= render 'extranet/persons/person', person: person %>
+        </div>
+      <% end %>
+    </div>
+    <%= paginate @people, theme: 'bootstrap-5' %>
+
+  </div>
+</div>
diff --git a/db/migrate/20220425152944_add_name_to_university_persons.rb b/db/migrate/20220425152944_add_name_to_university_persons.rb
new file mode 100644
index 000000000..dbe49902d
--- /dev/null
+++ b/db/migrate/20220425152944_add_name_to_university_persons.rb
@@ -0,0 +1,5 @@
+class AddNameToUniversityPersons < ActiveRecord::Migration[6.1]
+  def change
+    add_column :university_people, :name, :string
+  end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 9344a9d83..604f8b5a6 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
 #
 # It's strongly recommended that you check this file into your version control system.
 
-ActiveRecord::Schema.define(version: 2022_04_21_093107) do
+ActiveRecord::Schema.define(version: 2022_04_25_152944) do
 
   # These are extensions that must be enabled in order to support this database
   enable_extension "pgcrypto"
@@ -488,6 +488,23 @@ ActiveRecord::Schema.define(version: 2022_04_21_093107) do
     t.index ["university_id"], name: "index_education_schools_on_university_id"
   end
 
+  create_table "external_organizations", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
+    t.string "title"
+    t.text "description"
+    t.string "address"
+    t.string "zipcode"
+    t.string "city"
+    t.string "country"
+    t.string "website"
+    t.string "phone"
+    t.string "mail"
+    t.boolean "active"
+    t.string "sirene"
+    t.integer "kind"
+    t.datetime "created_at", precision: 6, null: false
+    t.datetime "updated_at", precision: 6, null: false
+  end
+
   create_table "languages", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
     t.string "name"
     t.string "iso_code"
@@ -671,6 +688,7 @@ ActiveRecord::Schema.define(version: 2022_04_21_093107) do
     t.string "linkedin"
     t.boolean "is_alumnus", default: false
     t.text "description_short"
+    t.string "name"
     t.index ["university_id"], name: "index_university_people_on_university_id"
     t.index ["user_id"], name: "index_university_people_on_user_id"
   end
-- 
GitLab