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

Support multiple content types in details fields #3067

Open
wants to merge 8 commits into
base: flatten-graphql-edition
Choose a base branch
from
9 changes: 8 additions & 1 deletion app/graphql/sources/linked_to_editions_source.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,18 @@ def initialize(parent_object:)
# rubocop:enable Lint/MissingSuper

def fetch(link_types)
all_links = @object.document.link_set_links
link_set_links = @object.document.link_set_links
.includes(target_documents: @content_store) # content_store is :live or :draft (a Document has_one Edition by that name)
.where(link_type: link_types)
.where(target_documents: { locale: "en" })

edition_links = @object.links
.includes(target_documents: @content_store) # content_store is :live or :draft (a Document has_one Edition by that name)
.where(link_type: link_types)
.where(target_documents: { locale: "en" })

all_links = link_set_links + edition_links

link_types_map = link_types.index_with { [] }

all_links.each_with_object(link_types_map) { |link, hash|
Expand Down
34 changes: 34 additions & 0 deletions app/graphql/sources/reverse_linked_to_editions_source.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
module Sources
class ReverseLinkedToEditionsSource < GraphQL::Dataloader::Source
# rubocop:disable Lint/MissingSuper
def initialize(parent_object:)
@object = parent_object
@content_store = parent_object.content_store.to_sym
end
# rubocop:enable Lint/MissingSuper

def fetch(link_types)
all_links = @object
.document
.reverse_links
.includes(source_documents: @content_store)
.where(link_type: link_types)

link_types_map = link_types.index_with { [] }

all_links.each_with_object(link_types_map) { |link, hash|
if link.link_set
hash[link.link_type].concat(editions_for_link_set_link(link))
elsif link.edition
hash[link.link_type] << link.edition
end
}.values
end

private

def editions_for_link_set_link(link)
link.source_documents.map { |document| document.send(@content_store) }
end
end
end
9 changes: 9 additions & 0 deletions app/graphql/types/base_object.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,14 @@ def self.links_field(field_name_and_link_type, graphql_field_type)
.load(field_name_and_link_type.to_s)
end
end

def self.reverse_links_field(field_name_and_link_type, belongs_to, graphql_field_type)
field(field_name_and_link_type.to_sym, graphql_field_type)

define_method(field_name_and_link_type.to_sym) do
dataloader.with(Sources::ReverseLinkedToEditionsSource, parent_object: object)
.load(belongs_to.to_s)
end
end
end
end
243 changes: 169 additions & 74 deletions app/graphql/types/edition_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,168 @@ class WithdrawnNotice < Types::BaseObject
field :withdrawn_at, GraphQL::Types::ISO8601DateTime
end

class EditionLinks < Types::BaseObject
links_field :active_top_level_browse_page, [EditionType]
links_field :associated_taxons, [EditionType]
links_field :available_translations, [EditionType]
links_field :contact, [EditionType]
links_field :contacts, [EditionType]
links_field :content_owners, [EditionType]
links_field :corporate_information_pages, [EditionType]
links_field :current_prime_minister, [EditionType]
links_field :documents, [EditionType]
links_field :email_alert_signup, [EditionType]
links_field :embed, [EditionType]
links_field :fatality_notices, [EditionType]
links_field :featured_policies, [EditionType]
links_field :field_of_operation, [EditionType]
links_field :fields_of_operation, [EditionType]
links_field :finder, [EditionType]
links_field :government, [EditionType]
links_field :historical_accounts, [EditionType]
links_field :home_page_offices, [EditionType]
links_field :lead_organisations, [EditionType]
links_field :linked_items, [EditionType]
links_field :main_office, [EditionType]
links_field :mainstream_browse_pages, [EditionType]
links_field :manual, [EditionType]
links_field :meets_user_needs, [EditionType]
links_field :ministerial, [EditionType]
links_field :office_staff, [EditionType]
links_field :ordered_board_members, [EditionType]
links_field :ordered_chief_professional_officers, [EditionType]
links_field :ordered_child_organisations, [EditionType]
links_field :ordered_contacts, [EditionType]
links_field :ordered_featured_policies, [EditionType]
links_field :ordered_foi_contacts, [EditionType]
links_field :ordered_high_profile_groups, [EditionType]
links_field :ordered_military_personnel, [EditionType]
links_field :ordered_ministers, [EditionType]
links_field :ordered_parent_organisations, [EditionType]
links_field :ordered_related_items_overrides, [EditionType]
links_field :ordered_related_items, [EditionType]
links_field :ordered_roles, [EditionType]
links_field :ordered_special_representatives, [EditionType]
links_field :ordered_successor_organisations, [EditionType]
links_field :ordered_traffic_commissioners, [EditionType]
links_field :organisations, [EditionType]
links_field :original_primary_publishing_organisation, [EditionType]
links_field :pages_part_of_step_nav, [EditionType]
links_field :pages_related_to_step_nav, [EditionType]
links_field :pages_secondary_to_step_nav, [EditionType]
links_field :parent_taxons, [EditionType]
links_field :parent, [EditionType]
links_field :people, [EditionType]
links_field :person, [EditionType]
links_field :policy_areas, [EditionType]
links_field :popular_links, [EditionType]
links_field :primary_publishing_organisation, [EditionType]
links_field :primary_role_person, [EditionType]
links_field :related_guides, [EditionType]
links_field :related_mainstream_content, [EditionType]
links_field :related_policies, [EditionType]
links_field :related_statistical_data_sets, [EditionType]
links_field :related_topics, [EditionType]
links_field :related, [EditionType]
links_field :role, [EditionType]
links_field :roles, [EditionType]
links_field :root_taxon, [EditionType]
links_field :second_level_browse_pages, [EditionType]
links_field :secondary_role_person, [EditionType]
links_field :sections, [EditionType]
links_field :service_manual_topics, [EditionType]
links_field :speaker, [EditionType]
links_field :sponsoring_organisations, [EditionType]
links_field :suggested_ordered_related_items, [EditionType]
links_field :take_part_pages, [EditionType]
links_field :taxonomy_topic_email_override, [EditionType]
links_field :taxons, [EditionType]
links_field :top_level_browse_pages, [EditionType]
links_field :topical_events, [EditionType]
links_field :world_locations, [EditionType]
links_field :worldwide_organisation, [EditionType]
links_field :worldwide_organisations, [EditionType]

reverse_links_field :child_taxons, :parent_taxons, [EditionType]
reverse_links_field :children, :parent, [EditionType]
reverse_links_field :document_collections, :documents, [EditionType]
reverse_links_field :level_one_taxons, :root_taxon, [EditionType]
reverse_links_field :ministers, :ministerial, [EditionType]
reverse_links_field :part_of_step_navs, :pages_part_of_step_nav, [EditionType]
reverse_links_field :policies, :working_groups, [EditionType]
reverse_links_field :related_to_step_navs, :pages_related_to_step_nav, [EditionType]
reverse_links_field :secondary_to_step_navs, :secondary_to_step_navs, [EditionType]

field :role_appointments, [EditionType]

def role_appointments
if object.document_type == "role" || object.document_type == "ministerial_role"
dataloader.with(Sources::ReverseLinkedToEditionsSource, parent_object: object)
.load("role")
else
dataloader.with(Sources::ReverseLinkedToEditionsSource, parent_object: object)
.load("person")
end
end

def available_translations
Presenters::Queries::AvailableTranslations.by_edition(object)
.translations.fetch(:available_translations, [])
end
end

class Details < Types::BaseObject
class Image < Types::BaseObject
field :url, String
field :alt_text, String
end

class Logo < Types::BaseObject
field :crest, String
field :formatted_title, String
end

class WhipOrganisation < Types::BaseObject
field :label, String
field :sort_order, Integer
end

field :body, String
field :brand, String
field :change_history, GraphQL::Types::JSON
field :current, Boolean
field :default_news_image, Image
field :display_date, GraphQL::Types::ISO8601DateTime
field :emphasised_organisations, GraphQL::Types::JSON
field :ended_on, GraphQL::Types::ISO8601DateTime
field :first_public_at, GraphQL::Types::ISO8601DateTime
field :image, Image
field :international_delegations, [EditionType], null: false
field :logo, Logo
field :political, Boolean
field :privy_counsellor, Boolean
field :role_payment_type, String
field :seniority, Integer
field :started_on, GraphQL::Types::ISO8601DateTime
field :supports_historical_accounts, Boolean
field :whip_organisation, WhipOrganisation
field :world_locations, [EditionType], null: false
end

field :active, Boolean, null: false
field :analytics_identifier, String
field :base_path, String
field :content_id, ID
field :current, Boolean
field :description, String
field :details, GraphQL::Types::JSON, null: false
field :details, Details
field :document_type, String
field :ended_on, GraphQL::Types::ISO8601DateTime
field :first_published_at, GraphQL::Types::ISO8601DateTime, null: false
field :iso2, String
field :links, EditionLinks, method: :itself
field :locale, String, null: false
field :name, String, null: false
field :phase, String, null: false
field :public_updated_at, GraphQL::Types::ISO8601DateTime, null: false
field :publishing_app, String
Expand All @@ -23,11 +177,25 @@ class WithdrawnNotice < Types::BaseObject
field :rendering_app, String
field :scheduled_publishing_delay_seconds, Int
field :schema_name, String
field :slug, String, null: false
field :started_on, GraphQL::Types::ISO8601DateTime
field :state, String
field :supports_historical_accounts, Boolean
field :title, String, null: false
field :updated_at, GraphQL::Types::ISO8601DateTime
field :web_url, String
field :withdrawn_notice, WithdrawnNotice

def details
Presenters::ContentTypeResolver.new("text/html").resolve(
Presenters::DetailsPresenter.new(
object.details,
Presenters::ChangeHistoryPresenter.new(object),
Presenters::ContentEmbedPresenter.new(object),
).details,
)
end

def withdrawn_notice
return nil unless object.unpublishing&.withdrawal?

Expand All @@ -43,79 +211,6 @@ def not_stored_in_publishing_api
alias_method :publishing_scheduled_at, :not_stored_in_publishing_api
alias_method :scheduled_publishing_delay_seconds, :not_stored_in_publishing_api

class Translation < Types::BaseObject
field :locale, String
field :base_path, String
end

class GovernmentDetails < Types::BaseObject
field :current, Boolean
end

class GovernmentLink < Types::BaseObject
field :base_path, String
field :content_id, String
field :details, GovernmentDetails
field :title, String
end

class OrganisationLink < Types::BaseObject
field :base_path, String
field :content_id, String
field :title, String
end

class PersonLink < Types::BaseObject
field :base_path, String
field :content_id, String
field :title, String
end

class Taxon < Types::BaseObject
field :base_path, String
field :content_id, String
field :document_type, String
field :phase, String
field :title, String
end

class TaxonLink < Taxon
class TaxonLinks < Types::BaseObject
links_field :parent_taxons, [Taxon]
end

field :links, TaxonLinks, method: :itself
end

class TopicalEventLink < Types::BaseObject
field :base_path, String
field :content_id, String
field :title, String
end

class WorldLocationLink < Types::BaseObject
field :base_path, String
field :content_id, String
field :title, String
end

class EditionLinks < Types::BaseObject
field :available_translations, [Translation]
links_field :government, [GovernmentLink]
links_field :organisations, [OrganisationLink]
links_field :people, [PersonLink]
links_field :taxons, [TaxonLink]
links_field :topical_events, [TopicalEventLink]
links_field :world_locations, [WorldLocationLink]

def available_translations
Presenters::Queries::AvailableTranslations.by_edition(object)
.translations.fetch(:available_translations, [])
end
end

field :links, EditionLinks, method: :itself

private

def presented_edition
Expand Down
12 changes: 0 additions & 12 deletions app/graphql/types/news_article_type.rb

This file was deleted.

5 changes: 2 additions & 3 deletions app/graphql/types/query_type/edition_type_or_subtype.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ class EditionTypeOrSubtype < Types::BaseUnion
EDITION_TYPES = [
Types::EditionType,
Types::MinistersIndexType,
Types::NewsArticleType,
Types::RoleType,
Types::WorldIndexType,
].freeze

possible_types(*EDITION_TYPES)
Expand All @@ -18,6 +15,8 @@ def resolve_type(object, _context)
document_type = object.document_type

matching_edition_subtype = Types::EditionType.descendants.find do |edition_subtype|
next unless edition_subtype.respond_to?(:document_types)

edition_subtype.document_types.include?(document_type)
end

Expand Down
Loading
Loading