Skip to content

Commit

Permalink
Merge pull request #3845 from alphagov/graphql-roles
Browse files Browse the repository at this point in the history
Use GraphQL for rendering Role page
  • Loading branch information
mike3985 authored Nov 25, 2024
2 parents 6b426a4 + 3cb6f42 commit 82b122d
Show file tree
Hide file tree
Showing 8 changed files with 454 additions and 136 deletions.
11 changes: 9 additions & 2 deletions app/controllers/roles_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,15 @@ class RolesController < ApplicationController
around_action :switch_locale

def show
@role = Role.find!(request.path)
if Features.graphql_feature_enabled? || params.include?(:graphql)
@role = Graphql::Role.find!(request.path)
content_item_data = @role.content_item
else
@role = Role.find!(request.path)
content_item_data = @role.content_item.content_item_data
end

setup_content_item_and_navigation_helpers(@role)
render :show, locals: { role: @role }
render :show, locals: { role: RolePresenter.new(content_item_data) }
end
end
17 changes: 17 additions & 0 deletions app/models/graphql/role.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class Graphql::Role
attr_reader :content_item

def initialize(content_item)
@content_item = content_item
end

def self.find!(base_path)
query = Graphql::RoleQuery.new(base_path).query

edition = Services.publishing_api.graphql_query(query)
.dig("data", "edition")
.deep_transform_keys(&:underscore)

new(edition)
end
end
116 changes: 0 additions & 116 deletions app/models/role.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
require "active_model"

class Role
include ActiveModel::Model

attr_reader :content_item

def initialize(content_item)
Expand All @@ -13,116 +9,4 @@ def self.find!(base_path)
content_item = ContentItem.find!(base_path)
new(content_item)
end

def base_path
content_item_data["base_path"]
end

def title
content_item_data["title"]
end

def responsibilities
details["body"]
end

def organisations
links["ordered_parent_organisations"]
end

def currently_occupied?
current_holder.present?
end

def current_holder
@current_holder ||= role_holders(current: true)
.first
&.dig("links", "person")
&.first
end

def current_holder_biography
current_holder["details"]["body"]
end

def past_holders
@past_holders ||= role_holders(current: false)
.reverse
.map do |rh|
rh.dig("links", "person")
&.first
&.tap do |hash|
hash["details"]["start_year"] = Time.zone.parse(rh["details"]["started_on"]).year
hash["details"]["end_year"] = Time.zone.parse(rh["details"]["ended_on"]).year
end
end
end

def link_to_person
current_holder["base_path"]
end

def translations
available_translations.map do |translation|
translation
.slice(:locale, :base_path)
.merge(
text: language_name(translation[:locale]),
active: locale == translation[:locale],
)
end
end

def locale
content_item_data["locale"]
end

def announcements
@announcements ||= AnnouncementsPresenter.new(slug, slug_prefix: "ministers", filter_key: "roles")
end

def supports_historical_accounts?
details["supports_historical_accounts"]
end

def past_holders_url
{
"prime-minister" => "/government/history/past-prime-ministers",
"chancellor-of-the-exchequer" => "/government/history/past-chancellors",
"secretary-of-state-for-foreign-commonwealth-and-development-affairs" => "/government/history/past-foreign-secretaries",
"foreign-secretary" => "/government/history/past-foreign-secretaries",
}[slug]
end

private

def content_item_data
content_item.content_item_data
end

def links
content_item_data["links"]
end

def details
content_item_data["details"]
end

def language_name(language)
I18n.t("shared.language_name", locale: language)
end

def available_translations
links["available_translations"].map(&:symbolize_keys)
end

def slug
base_path.split("/").last
end

def role_holders(current:)
links.fetch("role_appointments", [])
.find_all { |rh| rh["details"]["current"] == current }
.sort_by { |rh| rh["details"]["started_on"] }
end
end
115 changes: 115 additions & 0 deletions app/presenters/role_presenter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
class RolePresenter
def initialize(content_item_data)
@content_item_data = content_item_data
end

def base_path
content_item_data["base_path"]
end

def title
content_item_data["title"]
end

def responsibilities
details["body"]
end

def organisations
links["ordered_parent_organisations"]
end

def currently_occupied?
current_holder.present?
end

def current_holder
@current_holder ||= role_holders(current: true)
.first
&.dig("links", "person")
&.first
end

def current_holder_biography
current_holder["details"]["body"]
end

def past_holders
@past_holders ||= role_holders(current: false)
.reverse
.map do |rh|
rh.dig("links", "person")
&.first
&.tap do |hash|
hash["details"]["start_year"] = Time.zone.parse(rh["details"]["started_on"]).year
hash["details"]["end_year"] = Time.zone.parse(rh["details"]["ended_on"]).year
end
end
end

def link_to_person
current_holder["base_path"]
end

def translations
available_translations.map do |translation|
translation
.slice(:locale, :base_path)
.merge(
text: language_name(translation[:locale]),
active: locale == translation[:locale],
)
end
end

def locale
content_item_data["locale"]
end

def announcements
@announcements ||= AnnouncementsPresenter.new(slug, slug_prefix: "ministers", filter_key: "roles")
end

def supports_historical_accounts?
details["supports_historical_accounts"]
end

def past_holders_url
{
"prime-minister" => "/government/history/past-prime-ministers",
"chancellor-of-the-exchequer" => "/government/history/past-chancellors",
"secretary-of-state-for-foreign-commonwealth-and-development-affairs" => "/government/history/past-foreign-secretaries",
"foreign-secretary" => "/government/history/past-foreign-secretaries",
}[slug]
end

private

attr_reader :content_item_data

def links
content_item_data["links"]
end

def details
content_item_data["details"]
end

def language_name(language)
I18n.t("shared.language_name", locale: language)
end

def available_translations
links["available_translations"].map(&:symbolize_keys)
end

def slug
base_path.split("/").last
end

def role_holders(current:)
links.fetch("role_appointments", [])
.find_all { |rh| rh["details"]["current"] == current }
.sort_by { |rh| rh["details"]["started_on"] }
end
end
55 changes: 55 additions & 0 deletions app/queries/graphql/role_query.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
class Graphql::RoleQuery
def initialize(base_path)
@base_path = base_path
end

def query
<<-QUERY
{
edition(basePath: "#{@base_path}") {
... on Role {
basePath
locale
title
details {
body
supportsHistoricalAccounts
}
links {
availableTranslations {
basePath
locale
}
roleAppointments {
details {
current
endedOn
startedOn
}
links {
person {
basePath
title
details {
body
}
}
}
}
orderedParentOrganisations {
basePath
title
}
}
}
}
}
QUERY
end
end
Loading

0 comments on commit 82b122d

Please sign in to comment.