From b9f1a49619ffba902610a32e8ba55e4f13c992bc Mon Sep 17 00:00:00 2001
From: pabois <pierreandre.boissinot@noesya.coop>
Date: Thu, 28 Oct 2021 11:44:19 +0200
Subject: [PATCH] wip authors

---
 .../website/authors_controller.rb             | 62 +++++++++++++++++++
 app/models/communication/website.rb           | 17 ++++-
 app/models/communication/website/author.rb    | 43 +++++++++++++
 app/models/user.rb                            |  3 +-
 .../website/authors/_form.html.erb            | 32 ++++++++++
 .../website/authors/_list.html.erb            | 27 ++++++++
 .../website/authors/edit.html.erb             |  3 +
 .../website/authors/index.html.erb            |  9 +++
 .../website/authors/new.html.erb              |  3 +
 .../website/authors/show.html.erb             | 46 ++++++++++++++
 .../website/categories/_form.html.erb         |  2 +-
 .../website/pages/_form.html.erb              |  2 +-
 .../website/posts/_form.html.erb              |  2 +-
 config/locales/communication/en.yml           | 16 ++++-
 config/locales/communication/fr.yml           | 16 ++++-
 config/routes/admin/communication.rb          |  1 +
 ...02_create_communication_website_authors.rb | 17 +++++
 db/schema.rb                                  | 19 +++++-
 18 files changed, 306 insertions(+), 14 deletions(-)
 create mode 100644 app/controllers/admin/communication/website/authors_controller.rb
 create mode 100644 app/models/communication/website/author.rb
 create mode 100644 app/views/admin/communication/website/authors/_form.html.erb
 create mode 100644 app/views/admin/communication/website/authors/_list.html.erb
 create mode 100644 app/views/admin/communication/website/authors/edit.html.erb
 create mode 100644 app/views/admin/communication/website/authors/index.html.erb
 create mode 100644 app/views/admin/communication/website/authors/new.html.erb
 create mode 100644 app/views/admin/communication/website/authors/show.html.erb
 create mode 100644 db/migrate/20211028090402_create_communication_website_authors.rb

diff --git a/app/controllers/admin/communication/website/authors_controller.rb b/app/controllers/admin/communication/website/authors_controller.rb
new file mode 100644
index 000000000..ccc428fb9
--- /dev/null
+++ b/app/controllers/admin/communication/website/authors_controller.rb
@@ -0,0 +1,62 @@
+class Admin::Communication::Website::AuthorsController < Admin::Communication::Website::ApplicationController
+  load_and_authorize_resource class: Communication::Website::Author
+
+  def index
+    @authors = @website.authors.ordered.page(params[:page])
+    breadcrumb
+  end
+
+  def show
+    breadcrumb
+  end
+
+  def new
+    @author.website = @website
+    breadcrumb
+  end
+
+  def edit
+    breadcrumb
+    add_breadcrumb t('edit')
+  end
+
+  def create
+    @author.university = current_university
+    @author.website = @website
+    if @author.save
+      redirect_to admin_communication_website_author_path(@author), notice: t('admin.successfully_created_html', model: @author.to_s)
+    else
+      breadcrumb
+      render :new, status: :unprocessable_entity
+    end
+  end
+
+  def update
+    if @author.update(author_params)
+      redirect_to admin_communication_website_author_path(@author), notice: t('admin.successfully_updated_html', model: @author.to_s)
+    else
+      breadcrumb
+      add_breadcrumb t('edit')
+      render :edit, status: :unprocessable_entity
+    end
+  end
+
+  def destroy
+    @author.destroy
+    redirect_to admin_communication_website_authors_url, notice: t('admin.successfully_destroyed_html', model: @author.to_s)
+  end
+
+  protected
+
+  def breadcrumb
+    super
+    add_breadcrumb  Communication::Website::Author.model_name.human(count: 2),
+                    admin_communication_website_authors_path
+    breadcrumb_for @author
+  end
+
+  def author_params
+    params.require(:communication_website_author)
+          .permit(:university_id, :website_id, :first_name, :last_name, :biography, :slug, :user_id)
+  end
+end
diff --git a/app/models/communication/website.rb b/app/models/communication/website.rb
index 95edecc51..583e808d7 100644
--- a/app/models/communication/website.rb
+++ b/app/models/communication/website.rb
@@ -25,9 +25,20 @@
 class Communication::Website < ApplicationRecord
   belongs_to :university
   belongs_to :about, polymorphic: true, optional: true
-  has_many :pages, foreign_key: :communication_website_id
-  has_many :posts, foreign_key: :communication_website_id
-  has_many :categories, class_name: 'Communication::Website::Category', foreign_key: :communication_website_id
+  has_many :pages,
+           foreign_key: :communication_website_id,
+           dependent: :destroy
+  has_many :posts,
+           foreign_key: :communication_website_id,
+           dependent: :destroy
+  has_many :categories,
+           class_name: 'Communication::Website::Category',
+           foreign_key: :communication_website_id,
+           dependent: :destroy
+  has_many :authors,
+           class_name: 'Communication::Website::Author',
+           foreign_key: :communication_website_id,
+           dependent: :destroy
   has_one :imported_website,
           class_name: 'Communication::Website::Imported::Website',
           dependent: :destroy
diff --git a/app/models/communication/website/author.rb b/app/models/communication/website/author.rb
new file mode 100644
index 000000000..556463ae1
--- /dev/null
+++ b/app/models/communication/website/author.rb
@@ -0,0 +1,43 @@
+# == Schema Information
+#
+# Table name: communication_website_authors
+#
+#  id                       :uuid             not null, primary key
+#  first_name               :string
+#  last_name                :string
+#  slug                     :string
+#  created_at               :datetime         not null
+#  updated_at               :datetime         not null
+#  communication_website_id :uuid             not null
+#  university_id            :uuid             not null
+#  user_id                  :uuid
+#
+# Indexes
+#
+#  idx_comm_website_authors_on_communication_website_id  (communication_website_id)
+#  index_communication_website_authors_on_university_id  (university_id)
+#  index_communication_website_authors_on_user_id        (user_id)
+#
+# Foreign Keys
+#
+#  fk_rails_...  (communication_website_id => communication_websites.id)
+#  fk_rails_...  (university_id => universities.id)
+#  fk_rails_...  (user_id => users.id)
+#
+class Communication::Website::Author < ApplicationRecord
+  include WithSlug
+
+  has_rich_text :biography
+
+  belongs_to :university
+  belongs_to :user, optional: true
+  belongs_to :website,
+             foreign_key: :communication_website_id
+
+  scope :ordered, -> { order(:last_name, :first_name) }
+
+  def to_s
+    "#{last_name} #{first_name}"
+  end
+
+end
diff --git a/app/models/user.rb b/app/models/user.rb
index 67d95f094..38a69bdff 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -61,7 +61,8 @@ class User < ApplicationRecord
 
   belongs_to :university
   belongs_to :language
-  has_one :researcher, class_name: 'Research::Researcher'
+  has_one :researcher, class_name: 'Research::Researcher', dependent: :nullify
+  has_one :auhtor, class_name: 'Communication::Website::Author', dependent: :nullify
 
   scope :ordered, -> { order(:last_name, :first_name) }
 
diff --git a/app/views/admin/communication/website/authors/_form.html.erb b/app/views/admin/communication/website/authors/_form.html.erb
new file mode 100644
index 000000000..29fa4d830
--- /dev/null
+++ b/app/views/admin/communication/website/authors/_form.html.erb
@@ -0,0 +1,32 @@
+<%= simple_form_for [:admin, author] do |f| %>
+  <div class="row">
+    <div class="col-md-8">
+      <div class="card flex-fill w-100">
+        <div class="card-header">
+          <h5 class="card-title mb-0"><%= t('communication.website.content') %></h5>
+        </div>
+        <div class="card-body">
+          <%= f.input :first_name %>
+          <%= f.input :last_name %>
+          <%= f.input :biography, as: :rich_text_area %>
+        </div>
+      </div>
+    </div>
+    <div class="col-md-4">
+      <div class="card flex-fill w-100">
+        <div class="card-header">
+          <h5 class="card-title mb-0"><%= t('communication.website.metadata') %></h5>
+        </div>
+        <div class="card-body">
+          <%= f.input :slug, as: :string if author.persisted? %>
+          <%= f.association :user, collection: current_university.users.ordered %>
+          <ul>
+          </ul>
+        </div>
+      </div>
+    </div>
+  </div>
+  <% content_for :action_bar_right do %>
+    <%= submit f %>
+  <% end %>
+<% end %>
diff --git a/app/views/admin/communication/website/authors/_list.html.erb b/app/views/admin/communication/website/authors/_list.html.erb
new file mode 100644
index 000000000..96380bb00
--- /dev/null
+++ b/app/views/admin/communication/website/authors/_list.html.erb
@@ -0,0 +1,27 @@
+<table class="<%= table_classes %>">
+  <thead>
+    <tr>
+      <th><%= Communication::Website::Author.human_attribute_name('name') %></th>
+      <th></th>
+    </tr>
+  </thead>
+  <tbody>
+    <% authors.each do |author| %>
+      <tr>
+        <td><%= link_to author, admin_communication_website_author_path(website_id: author.website.id, id: author.id) %></td>
+        <td class="text-end">
+          <div class="btn-group" role="group">
+            <%= link_to t('edit'),
+                      edit_admin_communication_website_author_path(website_id: author.website.id, id: author.id),
+                      class: button_classes %>
+            <%= link_to t('delete'),
+                      admin_communication_website_author_path(website_id: author.website.id, id: author.id),
+                      method: :delete,
+                      data: { confirm: t('please-confirm') },
+                      class: button_classes_danger %>
+          </div>
+        </td>
+      </tr>
+    <% end %>
+  </tbody>
+</table>
diff --git a/app/views/admin/communication/website/authors/edit.html.erb b/app/views/admin/communication/website/authors/edit.html.erb
new file mode 100644
index 000000000..e0ab11a98
--- /dev/null
+++ b/app/views/admin/communication/website/authors/edit.html.erb
@@ -0,0 +1,3 @@
+<% content_for :title, @author %>
+
+<%= render 'form', author: @author %>
diff --git a/app/views/admin/communication/website/authors/index.html.erb b/app/views/admin/communication/website/authors/index.html.erb
new file mode 100644
index 000000000..bc327971e
--- /dev/null
+++ b/app/views/admin/communication/website/authors/index.html.erb
@@ -0,0 +1,9 @@
+<% content_for :title, "#{Communication::Website::Author.model_name.human(count: 2)} (#{@authors.total_count})" %>
+
+<%= render 'admin/communication/website/authors/list', authors: @authors %>
+<%= paginate @authors, theme: 'bootstrap-5' %>
+
+
+<% content_for :action_bar_right do %>
+  <%= create_link Communication::Website::Author %>
+<% end %>
diff --git a/app/views/admin/communication/website/authors/new.html.erb b/app/views/admin/communication/website/authors/new.html.erb
new file mode 100644
index 000000000..65a90853c
--- /dev/null
+++ b/app/views/admin/communication/website/authors/new.html.erb
@@ -0,0 +1,3 @@
+<% content_for :title, Communication::Website::Author.model_name.human %>
+
+<%= render 'form', author: @author %>
diff --git a/app/views/admin/communication/website/authors/show.html.erb b/app/views/admin/communication/website/authors/show.html.erb
new file mode 100644
index 000000000..c8e0111b5
--- /dev/null
+++ b/app/views/admin/communication/website/authors/show.html.erb
@@ -0,0 +1,46 @@
+<% content_for :title, @author %>
+
+<div class="row">
+
+  <div class="col-md-8">
+    <div class="card flex-fill w-100">
+      <div class="card-header">
+        <h5 class="card-title mb-0"><%= t('communication.website.content') %></h5>
+      </div>
+      <div class="card-body">
+        <p>
+          <strong><%= Communication::Website::Author.human_attribute_name('biography') %></strong>
+        </p>
+        <%= sanitize @author.biography %>
+      </div>
+    </div>
+  </div>
+
+  <div class="col-md-4">
+    <div class="card flex-fill w-100">
+      <div class="card-header">
+        <h5 class="card-title mb-0"><%= t('communication.website.metadata') %></h5>
+      </div>
+      <table class="<%= table_classes %>">
+        <tbody>
+          <tr>
+            <td width="150"><%= Communication::Website::Author.human_attribute_name('slug') %></td>
+            <td><%= @author.slug %></td>
+          </tr>
+          <% if @author.user %>
+            <tr>
+              <td width="150"><%= Communication::Website::Author.human_attribute_name('user') %></td>
+              <td><%= link_to_if can?(:read, @author.user), @author.user, admin_user_path(@author.user) %></td>
+            </tr>
+          <% end %>
+        </tbody>
+      </table>
+    </div>
+
+  </div>
+
+</div>
+
+<% content_for :action_bar_right do %>
+  <%= edit_link @author %>
+<% end %>
diff --git a/app/views/admin/communication/website/categories/_form.html.erb b/app/views/admin/communication/website/categories/_form.html.erb
index d1d631c95..2e54e3455 100644
--- a/app/views/admin/communication/website/categories/_form.html.erb
+++ b/app/views/admin/communication/website/categories/_form.html.erb
@@ -17,7 +17,7 @@
           <h5 class="card-title mb-0"><%= t('communication.website.metadata') %></h5>
         </div>
         <div class="card-body">
-          <%= f.input :slug, as: :string %>
+          <%= f.input :slug, as: :string if category.persisted? %>
           <%= f.association :parent, collection: category.list_of_other_categories, label_method: ->(p) { sanitize p[:label] }, value_method: ->(p) { p[:id] } %>
           <ul>
           </ul>
diff --git a/app/views/admin/communication/website/pages/_form.html.erb b/app/views/admin/communication/website/pages/_form.html.erb
index b4788412c..7a6fa6b13 100644
--- a/app/views/admin/communication/website/pages/_form.html.erb
+++ b/app/views/admin/communication/website/pages/_form.html.erb
@@ -18,7 +18,7 @@
           <h5 class="card-title mb-0"><%= t('communication.website.metadata') %></h5>
         </div>
         <div class="card-body">
-          <%= f.input :slug, as: :string %>
+          <%= f.input :slug, as: :string if page.persisted? %>
           <%= f.input :published %>
           <%= f.association :parent, collection: page.list_of_other_pages, label_method: ->(p) { sanitize p[:label] }, value_method: ->(p) { p[:id] } %>
           <ul>
diff --git a/app/views/admin/communication/website/posts/_form.html.erb b/app/views/admin/communication/website/posts/_form.html.erb
index 97b5236b1..46666ac96 100644
--- a/app/views/admin/communication/website/posts/_form.html.erb
+++ b/app/views/admin/communication/website/posts/_form.html.erb
@@ -18,7 +18,7 @@
           <h5 class="card-title mb-0"><%= t('communication.website.metadata') %></h5>
         </div>
         <div class="card-body">
-          <%= f.input :slug, as: :string %>
+          <%= f.input :slug, as: :string if post.persisted? %>
           <%= f.input :published %>
           <%= f.input :published_at, html5: true %>
           <%= f.association :categories, as: :check_boxes if @website.categories.any? %>
diff --git a/config/locales/communication/en.yml b/config/locales/communication/en.yml
index 0805e93a7..1ed44364d 100644
--- a/config/locales/communication/en.yml
+++ b/config/locales/communication/en.yml
@@ -25,6 +25,9 @@ en:
       communication/website:
         one: Website
         other: Websites
+      communication/website/author:
+        one: Author
+        other: Authors
       communication/website/category:
         one: Category
         other: Categories
@@ -49,12 +52,19 @@ en:
         about_: Independent website (no specific subject)
         about_Research::Journal: Journal website
         about_Education::School: School website
+      communication/website/author:
+        biography: Biography
+        first_name: First name
+        last_name: Last name
+        name: Name
+        slug: Slug
+        user: User
       communication/website/category:
         children: Children categories
         description: Description
         name: Name
         parent: Parent category
-        slug: slug
+        slug: Slug
       communication/website/imported/category:
         original: Original
       communication/website/imported/medium:
@@ -67,13 +77,13 @@ en:
         text: Text
         published: Published ?
         parent: Parent page
-        slug: slug
+        slug: Slug
         website: Website
       communication/website/post:
         title: Title
         description: Description (SEO)
         featured_image: Featured image
-        slug: slug
+        slug: Slug
         text: Text
         published: Published ?
         published_at: Publication date
diff --git a/config/locales/communication/fr.yml b/config/locales/communication/fr.yml
index 341b92716..0febf9dec 100644
--- a/config/locales/communication/fr.yml
+++ b/config/locales/communication/fr.yml
@@ -25,6 +25,9 @@ fr:
       communication/website:
         one: Site Web
         other: Sites Web
+      communication/website/author:
+        one: Auteur
+        other: Auteurs
       communication/website/category:
         one: Catégorie
         other: Catégories
@@ -48,12 +51,19 @@ fr:
         about_: Site indépendant (aucun sujet)
         about_Research::Journal: Site de revue scientifique
         about_Education::School: Site d'école
+      communication/website/author:
+        biography: Biographie
+        first_name: Prénom
+        last_name: Nom de famille
+        name: Nom
+        slug: Slug
+        user: Utilisateur
       communication/website/category:
         children: Catégories enfantes
         description: Description
         name: Nom
         parent: Catégorie parente
-        slug: slug
+        slug: Slug
       communication/website/imported/category:
         original: Original
       communication/website/imported/medium:
@@ -64,7 +74,7 @@ fr:
         featured_image: Image à la une
         parent: Page parente
         published: Publié ?
-        slug: slug
+        slug: Slug
         text: Texte
         title: Titre
         website: Site Web
@@ -74,7 +84,7 @@ fr:
         featured_image: Image à la une
         published: Publié ?
         published_at: Date de publication
-        slug: slug
+        slug: Slug
         text: Texte
         title: Titre
         website: Site Web
diff --git a/config/routes/admin/communication.rb b/config/routes/admin/communication.rb
index 436bbdbb2..01fafe077 100644
--- a/config/routes/admin/communication.rb
+++ b/config/routes/admin/communication.rb
@@ -20,6 +20,7 @@ namespace :communication do
         get :children
       end
     end
+    resources :authors, controller: 'website/authors'
     resources :posts, controller: 'website/posts'
   end
 end
diff --git a/db/migrate/20211028090402_create_communication_website_authors.rb b/db/migrate/20211028090402_create_communication_website_authors.rb
new file mode 100644
index 000000000..c47d37f13
--- /dev/null
+++ b/db/migrate/20211028090402_create_communication_website_authors.rb
@@ -0,0 +1,17 @@
+class CreateCommunicationWebsiteAuthors < ActiveRecord::Migration[6.1]
+  def change
+    create_table :communication_website_authors, id: :uuid do |t|
+      t.references :university, null: false, foreign_key: true, type: :uuid
+      t.references :user, foreign_key: true, type: :uuid
+      t.references :communication_website,
+                  null: false,
+                  foreign_key: { to_table: :communication_websites },
+                  type: :uuid,
+                  index: { name: 'idx_comm_website_authors_on_communication_website_id' }
+      t.string :last_name
+      t.string :first_name
+      t.string :slug
+      t.timestamps
+    end
+  end
+end
diff --git a/db/schema.rb b/db/schema.rb
index f07df88c2..880bc7757 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: 2021_10_27_131939) do
+ActiveRecord::Schema.define(version: 2021_10_28_090402) do
 
   # These are extensions that must be enabled in order to support this database
   enable_extension "pgcrypto"
@@ -78,6 +78,20 @@ ActiveRecord::Schema.define(version: 2021_10_27_131939) do
     t.index ["criterion_id"], name: "index_administration_qualiopi_indicators_on_criterion_id"
   end
 
+  create_table "communication_website_authors", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
+    t.uuid "university_id", null: false
+    t.uuid "user_id"
+    t.uuid "communication_website_id", null: false
+    t.string "last_name"
+    t.string "first_name"
+    t.string "slug"
+    t.datetime "created_at", precision: 6, null: false
+    t.datetime "updated_at", precision: 6, null: false
+    t.index ["communication_website_id"], name: "idx_comm_website_authors_on_communication_website_id"
+    t.index ["university_id"], name: "index_communication_website_authors_on_university_id"
+    t.index ["user_id"], name: "index_communication_website_authors_on_user_id"
+  end
+
   create_table "communication_website_categories", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
     t.uuid "university_id", null: false
     t.uuid "communication_website_id", null: false
@@ -426,6 +440,9 @@ ActiveRecord::Schema.define(version: 2021_10_27_131939) do
   add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
   add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id"
   add_foreign_key "administration_qualiopi_indicators", "administration_qualiopi_criterions", column: "criterion_id"
+  add_foreign_key "communication_website_authors", "communication_websites"
+  add_foreign_key "communication_website_authors", "universities"
+  add_foreign_key "communication_website_authors", "users"
   add_foreign_key "communication_website_categories", "communication_website_categories", column: "parent_id"
   add_foreign_key "communication_website_categories", "communication_websites"
   add_foreign_key "communication_website_categories", "universities"
-- 
GitLab