From 2e79183ff906bd7f541cab0dc4f4bd9e4d1a8005 Mon Sep 17 00:00:00 2001
From: Alex Newton
Date: Wed, 8 Jan 2025 12:09:45 +0000
Subject: [PATCH 1/3] Add ability to reorder social media links
---
...onable_social_media_accounts_controller.rb | 26 +++++++++++++++++++
app/models/social_media_account.rb | 5 ++++
...e_social_media_accounts_index_presenter.rb | 6 ++++-
.../worldwide_organisation_presenter.rb | 2 +-
.../index.html.erb | 21 +++++++++++----
.../reorder.html.erb | 26 +++++++++++++++++++
config/routes.rb | 4 +++
...4_add_ordering_to_social_media_accounts.rb | 5 ++++
db/schema.rb | 3 ++-
9 files changed, 90 insertions(+), 8 deletions(-)
create mode 100644 app/views/admin/editionable_social_media_accounts/reorder.html.erb
create mode 100644 db/migrate/20250108102234_add_ordering_to_social_media_accounts.rb
diff --git a/app/controllers/admin/editionable_social_media_accounts_controller.rb b/app/controllers/admin/editionable_social_media_accounts_controller.rb
index ce5cc4cea9f..953672ea2fb 100644
--- a/app/controllers/admin/editionable_social_media_accounts_controller.rb
+++ b/app/controllers/admin/editionable_social_media_accounts_controller.rb
@@ -46,6 +46,15 @@ def update
end
end
+ def reorder
+ if request.put?
+ update_ordering
+ redirect_to admin_edition_social_media_accounts_path(@edition), notice: "Social media accounts reordered"
+ else
+ @reorderable_social_media_accounts = @edition.social_media_accounts.order(:ordering)
+ end
+ end
+
private
def find_edition
@@ -62,8 +71,25 @@ def social_media_account_params
:social_media_service_id,
:title,
:url,
+ :ordering,
).merge(
socialable: @edition,
)
end
+
+ def extract_items_from_ordering_params
+ item_ordering = params[:ordering] || {}
+ item_ordering.permit!.to_h
+ .map { |item_id, ordering| [SocialMediaAccount.find(item_id), ordering.to_i] }
+ .sort_by { |_, ordering| ordering }
+ .map { |item, _| item }
+ .compact
+ end
+
+ def update_ordering
+ ordered_accounts = extract_items_from_ordering_params
+ ordered_accounts.each_with_index do |account, index|
+ account.update_order(index + 1)
+ end
+ end
end
diff --git a/app/models/social_media_account.rb b/app/models/social_media_account.rb
index 3df724291d9..59d66638884 100644
--- a/app/models/social_media_account.rb
+++ b/app/models/social_media_account.rb
@@ -24,4 +24,9 @@ def service_name
def display_name
title.presence || service_name
end
+
+ def update_order(new_order)
+ self.ordering = new_order
+ save!
+ end
end
diff --git a/app/presenters/editionable_social_media_accounts_index_presenter.rb b/app/presenters/editionable_social_media_accounts_index_presenter.rb
index 358e43a1edf..e1c99a476e3 100644
--- a/app/presenters/editionable_social_media_accounts_index_presenter.rb
+++ b/app/presenters/editionable_social_media_accounts_index_presenter.rb
@@ -8,7 +8,7 @@ def initialize(edition)
end
def social_media_accounts
- edition.social_media_accounts.map do |social_media_account|
+ order_social_media_accounts.map do |social_media_account|
{
title: social_media_account.service_name,
rows: social_media_account_rows(social_media_account),
@@ -17,6 +17,10 @@ def social_media_accounts
end
end
+ def order_social_media_accounts
+ @edition.social_media_accounts.order(:ordering)
+ end
+
private
def social_media_account_rows(social_media_account)
diff --git a/app/presenters/publishing_api/worldwide_organisation_presenter.rb b/app/presenters/publishing_api/worldwide_organisation_presenter.rb
index b8bd597d125..950bc93ba3b 100644
--- a/app/presenters/publishing_api/worldwide_organisation_presenter.rb
+++ b/app/presenters/publishing_api/worldwide_organisation_presenter.rb
@@ -151,7 +151,7 @@ def secondary_role_person
def social_media_links
return [] unless item.social_media_accounts.any?
- item.social_media_accounts.map do |social_media_account|
+ item.social_media_accounts.order(:ordering).map do |social_media_account|
{
href: social_media_account.url,
service_type: social_media_account.service_name.parameterize,
diff --git a/app/views/admin/editionable_social_media_accounts/index.html.erb b/app/views/admin/editionable_social_media_accounts/index.html.erb
index b32e6f09511..1e2f386f16e 100644
--- a/app/views/admin/editionable_social_media_accounts/index.html.erb
+++ b/app/views/admin/editionable_social_media_accounts/index.html.erb
@@ -18,11 +18,22 @@
<%= link_to "Add new social media account", new_admin_edition_social_media_account_path(@edition), class: "govuk-link govuk-link--no-visited-state" %>
- <%= render "govuk_publishing_components/components/heading", {
- text: "Social media accounts",
- font_size: "l",
- margin_bottom: 3,
- } %>
+
+
+ <%= render "govuk_publishing_components/components/heading", {
+ text: "Social media accounts",
+ font_size: "l",
+ margin_bottom: 3,
+ } %>
+
+ <% if @edition.social_media_accounts.many? %>
+
+
+ <%= link_to("Reorder", reorder_admin_edition_social_media_accounts_path(@edition), class: "govuk-link govuk-link--no-visited-state") %>
+
+
+ <% end %>
+
<% if @edition.social_media_accounts.any? %>
<% @editionable_social_media_accounts_index_presenter.social_media_accounts.each do |social_media_account| %>
diff --git a/app/views/admin/editionable_social_media_accounts/reorder.html.erb b/app/views/admin/editionable_social_media_accounts/reorder.html.erb
new file mode 100644
index 00000000000..b206af5de93
--- /dev/null
+++ b/app/views/admin/editionable_social_media_accounts/reorder.html.erb
@@ -0,0 +1,26 @@
+<% content_for :page_title, "Reorder social media accounts" %>
+<% content_for :title, "Reorder social media accounts" %>
+<% content_for :title_margin_bottom, 6 %>
+
+
+
+ <%= form_with url: reorder_admin_edition_social_media_accounts_path(@edition), method: :put do %>
+ <%= render "govuk_publishing_components/components/reorderable_list", {
+ items: @reorderable_social_media_accounts.map do |account|
+ {
+ id: account.id,
+ title: account.title,
+ }
+ end,
+ } %>
+
+
+ <%= render "govuk_publishing_components/components/button", {
+ text: "Update order",
+ } %>
+
+ <%= link_to("Cancel", admin_edition_social_media_accounts_path(@edition), class: "govuk-link govuk-link--no-visited-state") %>
+
+ <% end %>
+
+
diff --git a/config/routes.rb b/config/routes.rb
index ec2400c9561..70bb9363f64 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -250,6 +250,10 @@ def redirect(path, options = { prefix: Whitehall.router_prefix })
resources :lead_images, controller: "edition_lead_images", only: %i[update]
resources :social_media_accounts, only: %i[create destroy edit index new update], controller: "editionable_social_media_accounts" do
get :confirm_destroy, on: :member
+ collection do
+ get :reorder
+ put :reorder
+ end
end
end
diff --git a/db/migrate/20250108102234_add_ordering_to_social_media_accounts.rb b/db/migrate/20250108102234_add_ordering_to_social_media_accounts.rb
new file mode 100644
index 00000000000..9f6e765f4a6
--- /dev/null
+++ b/db/migrate/20250108102234_add_ordering_to_social_media_accounts.rb
@@ -0,0 +1,5 @@
+class AddOrderingToSocialMediaAccounts < ActiveRecord::Migration[7.1]
+ def change
+ add_column :social_media_accounts, :ordering, :integer
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 4b09da4056b..5fcfcf55d69 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[7.1].define(version: 2025_01_06_160308) do
+ActiveRecord::Schema[7.1].define(version: 2025_01_08_102234) do
create_table "assets", charset: "utf8mb3", force: :cascade do |t|
t.string "asset_manager_id", null: false
t.string "variant", null: false
@@ -1006,6 +1006,7 @@
t.datetime "created_at", precision: nil
t.datetime "updated_at", precision: nil
t.string "socialable_type"
+ t.integer "ordering"
t.index ["social_media_service_id"], name: "index_social_media_accounts_on_social_media_service_id"
t.index ["socialable_id"], name: "index_social_media_accounts_on_organisation_id"
end
From 84dff189347224c40f9862053f6bfda9cab3e5dc Mon Sep 17 00:00:00 2001
From: Alex Newton
Date: Wed, 8 Jan 2025 12:12:18 +0000
Subject: [PATCH 2/3] DRY up ordering parameter methods
---
app/controllers/admin/contacts_controller.rb | 10 +++-------
.../editionable_social_media_accounts_controller.rb | 12 ++++--------
app/controllers/admin/home_page_list_controller.rb | 2 +-
.../admin/worldwide_offices_controller.rb | 10 +++-------
app/controllers/concerns/orderable_items_concern.rb | 12 ++++++++++++
5 files changed, 23 insertions(+), 23 deletions(-)
create mode 100644 app/controllers/concerns/orderable_items_concern.rb
diff --git a/app/controllers/admin/contacts_controller.rb b/app/controllers/admin/contacts_controller.rb
index 13f77f06113..a3de8f0ae7f 100644
--- a/app/controllers/admin/contacts_controller.rb
+++ b/app/controllers/admin/contacts_controller.rb
@@ -1,4 +1,5 @@
class Admin::ContactsController < Admin::BaseController
+ include OrderableItemsConcern
before_action :find_contactable
before_action :find_contact, only: %i[edit update destroy confirm_destroy]
before_action :destroy_blank_contact_numbers, only: %i[create update]
@@ -82,13 +83,8 @@ def extract_show_on_home_page_param
@show_on_home_page = params[:contact].delete(:show_on_home_page)
end
- def extract_items_from_ordering_params
- item_ordering = params[:ordering] || {}
- item_ordering.permit!.to_h
- .map { |item_id, ordering| [Contact.find_by(id: item_id), ordering.to_i] }
- .sort_by { |_, ordering| ordering }
- .map { |item, _| item }
- .compact
+ def fetch_ordered_items
+ @ordered_items = extract_items_from_ordering_params(Contact)
end
def find_contactable
diff --git a/app/controllers/admin/editionable_social_media_accounts_controller.rb b/app/controllers/admin/editionable_social_media_accounts_controller.rb
index 953672ea2fb..1ebfc0fa7b7 100644
--- a/app/controllers/admin/editionable_social_media_accounts_controller.rb
+++ b/app/controllers/admin/editionable_social_media_accounts_controller.rb
@@ -1,4 +1,5 @@
class Admin::EditionableSocialMediaAccountsController < Admin::BaseController
+ include OrderableItemsConcern
before_action :find_edition
before_action :find_social_media_account, only: %i[confirm_destroy destroy edit update]
@@ -77,17 +78,12 @@ def social_media_account_params
)
end
- def extract_items_from_ordering_params
- item_ordering = params[:ordering] || {}
- item_ordering.permit!.to_h
- .map { |item_id, ordering| [SocialMediaAccount.find(item_id), ordering.to_i] }
- .sort_by { |_, ordering| ordering }
- .map { |item, _| item }
- .compact
+ def fetch_ordered_items
+ @ordered_items = extract_items_from_ordering_params(SocialMediaAccount)
end
def update_ordering
- ordered_accounts = extract_items_from_ordering_params
+ ordered_accounts = fetch_ordered_items
ordered_accounts.each_with_index do |account, index|
account.update_order(index + 1)
end
diff --git a/app/controllers/admin/home_page_list_controller.rb b/app/controllers/admin/home_page_list_controller.rb
index bc9d6f00706..bf01e2d64fe 100644
--- a/app/controllers/admin/home_page_list_controller.rb
+++ b/app/controllers/admin/home_page_list_controller.rb
@@ -7,7 +7,7 @@ def is_home_page_list_controller_for(list_name, opts)
redirect_proc = opts[:redirect_to]
home_page_list_controller_methods = Module.new do
define_method(:reorder_for_home_page) do
- reordered_items = extract_items_from_ordering_params
+ reordered_items = fetch_ordered_items
home_page_list_container.__send__(:"reorder_#{plural_name}_on_home_page!", reordered_items)
publish_container_to_publishing_api
redirect_to redirect_proc.call(home_page_list_container, home_page_list_item), notice: %(#{plural_name.titleize} on home page reordered successfully)
diff --git a/app/controllers/admin/worldwide_offices_controller.rb b/app/controllers/admin/worldwide_offices_controller.rb
index 92d1687a779..fb760b17417 100644
--- a/app/controllers/admin/worldwide_offices_controller.rb
+++ b/app/controllers/admin/worldwide_offices_controller.rb
@@ -1,4 +1,5 @@
class Admin::WorldwideOfficesController < Admin::BaseController
+ include OrderableItemsConcern
before_action :find_worldwide_organisation
before_action :find_worldwide_office, only: %i[edit update confirm_destroy destroy]
extend Admin::HomePageListController
@@ -94,13 +95,8 @@ def handle_show_on_home_page_param
end
end
- def extract_items_from_ordering_params
- item_ordering = params[:ordering] || {}
- item_ordering.permit!.to_h
- .map { |item_id, ordering| [WorldwideOffice.find_by(id: item_id), ordering.to_i] }
- .sort_by { |_, ordering| ordering }
- .map { |item, _| item }
- .compact
+ def fetch_ordered_items
+ @ordered_items = extract_items_from_ordering_params(WorldwideOffice)
end
def extract_show_on_home_page_param
diff --git a/app/controllers/concerns/orderable_items_concern.rb b/app/controllers/concerns/orderable_items_concern.rb
new file mode 100644
index 00000000000..94ceafe820c
--- /dev/null
+++ b/app/controllers/concerns/orderable_items_concern.rb
@@ -0,0 +1,12 @@
+module OrderableItemsConcern
+ extend ActiveSupport::Concern
+
+ def extract_items_from_ordering_params(model_class)
+ item_ordering = params[:ordering] || {}
+ item_ordering.permit!.to_h
+ .map { |item_id, ordering| [model_class.find_by(id: item_id), ordering.to_i] }
+ .sort_by { |_, ordering| ordering }
+ .map { |item, _| item }
+ .compact
+ end
+end
From 1a301efbf6324349b0865ff086e94b63d4cb1d9e Mon Sep 17 00:00:00 2001
From: Alex Newton
Date: Wed, 8 Jan 2025 14:48:44 +0000
Subject: [PATCH 3/3] Add tests for social media reordering'
---
...e_social_media_accounts_controller_test.rb | 23 +++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/test/functional/admin/editionable_social_media_accounts_controller_test.rb b/test/functional/admin/editionable_social_media_accounts_controller_test.rb
index e854f8c8a1e..46010ced30e 100644
--- a/test/functional/admin/editionable_social_media_accounts_controller_test.rb
+++ b/test/functional/admin/editionable_social_media_accounts_controller_test.rb
@@ -146,4 +146,27 @@ class Admin::EditionableSocialMediaAccountsControllerTest < ActionController::Te
assert_response :redirect
assert_empty @edition.social_media_accounts
end
+
+ view_test "GET :reorder displays the reorderable social media accounts" do
+ get :reorder, params: { edition_id: @edition }
+
+ assert_response :success
+ assert_select ".gem-c-reorderable-list__item", count: @edition.social_media_accounts.count
+ end
+
+ test "PUT :reorder updates the ordering of social media accounts" do
+ social_media_account1 = create(:social_media_account, socialable: @edition, ordering: 1)
+ social_media_account2 = create(:social_media_account, socialable: @edition, ordering: 2)
+
+ put :reorder,
+ params: { edition_id: @edition,
+ ordering: {
+ social_media_account2.id.to_s => "1",
+ social_media_account1.id.to_s => "2",
+ } }
+
+ assert_response :redirect
+ reordered_accounts = @edition.reload.social_media_accounts.where(id: [social_media_account1.id, social_media_account2.id]).order(:ordering)
+ assert_equal [social_media_account2, social_media_account1], reordered_accounts
+ end
end