Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reorder social media worldwide org #9796

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 3 additions & 7 deletions app/controllers/admin/contacts_controller.rb
Original file line number Diff line number Diff line change
@@ -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]
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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]

Expand Down Expand Up @@ -46,6 +47,15 @@ def update
end
end

def reorder
if request.put?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still not sure about serving two routes from the same controller method, would be interested to get the rest of the team's thoughts on that. I don't think it's a major issue but I don't think I've seen this done much in other places in Whitehall

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
Expand All @@ -62,8 +72,20 @@ def social_media_account_params
:social_media_service_id,
:title,
:url,
:ordering,
).merge(
socialable: @edition,
)
end

def fetch_ordered_items
@ordered_items = extract_items_from_ordering_params(SocialMediaAccount)
end

def update_ordering
ordered_accounts = fetch_ordered_items
ordered_accounts.each_with_index do |account, index|
account.update_order(index + 1)
end
Comment on lines +87 to +89
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this done transactionally on other ordering endpoints? Feels like the sort of operation that should either succeed completely or fail. If there isn't a database transaction we might end up with ordering conflicts if it fails for one of the accounts for some reason (e.g. validation error)

end
end
2 changes: 1 addition & 1 deletion app/controllers/admin/home_page_list_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
10 changes: 3 additions & 7 deletions app/controllers/admin/worldwide_offices_controller.rb
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need to be an instance variable?

end

def extract_show_on_home_page_param
Expand Down
12 changes: 12 additions & 0 deletions app/controllers/concerns/orderable_items_concern.rb
Original file line number Diff line number Diff line change
@@ -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
5 changes: 5 additions & 0 deletions app/models/social_media_account.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,9 @@ def service_name
def display_name
title.presence || service_name
end

def update_order(new_order)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would probably just use the update method from whatever object calls this - or, if you find there should be a transaction, you might want to figure out how to do a bulk update to the ordering column.

self.ordering = new_order
save!
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand All @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
21 changes: 16 additions & 5 deletions app/views/admin/editionable_social_media_accounts/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -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" %>
</p>

<%= render "govuk_publishing_components/components/heading", {
text: "Social media accounts",
font_size: "l",
margin_bottom: 3,
} %>
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<%= render "govuk_publishing_components/components/heading", {
text: "Social media accounts",
font_size: "l",
margin_bottom: 3,
} %>
</div>
<% if @edition.social_media_accounts.many? %>
<div class="govuk-grid-column-one-third">
<p class="govuk-body govuk-!-text-align-right">
<%= link_to("Reorder", reorder_admin_edition_social_media_accounts_path(@edition), class: "govuk-link govuk-link--no-visited-state") %>
</p>
</div>
<% end %>
</div>

<% if @edition.social_media_accounts.any? %>
<% @editionable_social_media_accounts_index_presenter.social_media_accounts.each do |social_media_account| %>
Expand Down
26 changes: 26 additions & 0 deletions app/views/admin/editionable_social_media_accounts/reorder.html.erb
Original file line number Diff line number Diff line change
@@ -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 %>

<div class="govuk-grid-row">
<div class="govuk-grid-column-full">
<%= 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,
} %>

<div class="govuk-button-group govuk-!-margin-bottom-6">
<%= 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") %>
</div>
<% end %>
</div>
</div>
4 changes: 4 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddOrderingToSocialMediaAccounts < ActiveRecord::Migration[7.1]
def change
add_column :social_media_accounts, :ordering, :integer
end
end
3 changes: 2 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Loading