diff --git a/Gemfile.lock b/Gemfile.lock index 04b177c049a..c71a9733cc8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -310,7 +310,7 @@ GEM govuk_personalisation (1.1.0) plek (>= 1.9.0) rails (>= 6, < 9) - govuk_publishing_components (46.0.0) + govuk_publishing_components (46.1.0) chartkick govuk_app_config govuk_personalisation (>= 0.7.0) diff --git a/lib/engines/content_block_manager/app/assets/stylesheets/content_block_manager/application.scss b/lib/engines/content_block_manager/app/assets/stylesheets/content_block_manager/application.scss index 248debc1bdc..08a3e85d331 100644 --- a/lib/engines/content_block_manager/app/assets/stylesheets/content_block_manager/application.scss +++ b/lib/engines/content_block_manager/app/assets/stylesheets/content_block_manager/application.scss @@ -1,4 +1,5 @@ @import "components/filter-options-component"; +@import "components/host-editions-rollup-component"; @import "components/host-editions-table-component"; @import "components/timeline-component"; diff --git a/lib/engines/content_block_manager/app/assets/stylesheets/content_block_manager/components/_host-editions-rollup-component.scss b/lib/engines/content_block_manager/app/assets/stylesheets/content_block_manager/components/_host-editions-rollup-component.scss new file mode 100644 index 00000000000..65d5ec7acf7 --- /dev/null +++ b/lib/engines/content_block_manager/app/assets/stylesheets/content_block_manager/components/_host-editions-rollup-component.scss @@ -0,0 +1,31 @@ +.rollup-details { + background: govuk-colour("light-grey"); + margin-bottom: govuk-spacing(8); + + .govuk-grid-column-full { + padding: 0; + } + + &__title { + @include govuk-visually-hidden; + } + + &__rollup-metric { + .gem-c-glance-metric { + border: none; + margin: govuk-spacing(6); + padding: 0; + + &__heading { + @include govuk-font(19, $weight: regular, $line-height: 1); + + min-height: 1em; + } + + &__context { + border: none; + min-height: 0; + } + } + } +} diff --git a/lib/engines/content_block_manager/app/components/content_block_manager/content_block/document/show/host_editions_rollup_component.html.erb b/lib/engines/content_block_manager/app/components/content_block_manager/content_block/document/show/host_editions_rollup_component.html.erb new file mode 100644 index 00000000000..0954a70a1c1 --- /dev/null +++ b/lib/engines/content_block_manager/app/components/content_block_manager/content_block/document/show/host_editions_rollup_component.html.erb @@ -0,0 +1,19 @@ +<div class="govuk-grid-row rollup-details"> + <div class="govuk-grid-column-full"> + <h2 class="rollup-details__title">Metrics</h2> + <% metrics.each do |name, value| %> + <div class="govuk-grid-column-one-quarter rollup-details__rollup-metric <%= name %>"> + <%= + render( + "govuk_publishing_components/components/glance_metric", + name: name.to_s.titleize, + figure: value[:figure], + measurement_display_label: value[:display_label], + measurement_explicit_label: value[:explicit_label], + heading_level: 3, + ) + %> + </div> + <% end %> + </div> +</div> diff --git a/lib/engines/content_block_manager/app/components/content_block_manager/content_block/document/show/host_editions_rollup_component.rb b/lib/engines/content_block_manager/app/components/content_block_manager/content_block/document/show/host_editions_rollup_component.rb new file mode 100644 index 00000000000..f1363012652 --- /dev/null +++ b/lib/engines/content_block_manager/app/components/content_block_manager/content_block/document/show/host_editions_rollup_component.rb @@ -0,0 +1,25 @@ +class ContentBlockManager::ContentBlock::Document::Show::HostEditionsRollupComponent < ViewComponent::Base + METRICS = %i[locations instances organisations views].freeze + + def initialize(rollup:) + @rollup = rollup + end + +private + + attr_reader :rollup + + def metrics + METRICS.index_with do |metric| + abbreviate(rollup.send(metric)) + end + end + + def abbreviate(number) + { + figure: number_to_human(number, format: "%n"), + display_label: number_to_human(number, format: "%u", units: { unit: "", thousand: "k", million: "m", billion: "b" }), + explicit_label: number_to_human(number, format: "%u"), + } + end +end diff --git a/lib/engines/content_block_manager/app/models/content_block_manager/host_content_items.rb b/lib/engines/content_block_manager/app/models/content_block_manager/host_content_items.rb index c2fd460f01a..d0002202ac2 100644 --- a/lib/engines/content_block_manager/app/models/content_block_manager/host_content_items.rb +++ b/lib/engines/content_block_manager/app/models/content_block_manager/host_content_items.rb @@ -1,9 +1,11 @@ module ContentBlockManager - class HostContentItems < Data.define(:items, :total, :total_pages) + class HostContentItems < Data.define(:items, :total, :total_pages, :rollup) extend Forwardable ARRAY_METHODS = ([].methods - Object.methods) def_delegators :items, *ARRAY_METHODS + + class Rollup < Data.define(:views, :locations, :instances, :organisations); end end end diff --git a/lib/engines/content_block_manager/app/services/content_block_manager/get_host_content_items.rb b/lib/engines/content_block_manager/app/services/content_block_manager/get_host_content_items.rb index 554f2bc9547..64e45a53fdb 100644 --- a/lib/engines/content_block_manager/app/services/content_block_manager/get_host_content_items.rb +++ b/lib/engines/content_block_manager/app/services/content_block_manager/get_host_content_items.rb @@ -34,7 +34,21 @@ def items ) end - ContentBlockManager::HostContentItems.new(items, content_items["total"], content_items["total_pages"]) + ContentBlockManager::HostContentItems.new( + items:, + total: content_items["total"], + total_pages: content_items["total_pages"], + rollup:, + ) + end + + def rollup + ContentBlockManager::HostContentItems::Rollup.new( + views: content_items["rollup"]["views"], + locations: content_items["rollup"]["locations"], + instances: content_items["rollup"]["instances"], + organisations: content_items["rollup"]["organisations"], + ) end private diff --git a/lib/engines/content_block_manager/app/views/content_block_manager/content_block/documents/show.html.erb b/lib/engines/content_block_manager/app/views/content_block_manager/content_block/documents/show.html.erb index 30b83d3ab34..094081d4962 100644 --- a/lib/engines/content_block_manager/app/views/content_block_manager/content_block/documents/show.html.erb +++ b/lib/engines/content_block_manager/app/views/content_block_manager/content_block/documents/show.html.erb @@ -6,6 +6,14 @@ } %> <% end %> +<%= + render( + ContentBlockManager::ContentBlock::Document::Show::HostEditionsRollupComponent.new( + rollup: @host_content_items.rollup, + ), + ) +%> + <div class="govuk-grid-row"> <div class="govuk-grid-column-full"> <h2 class="govuk-heading-m">Details</h2> diff --git a/lib/engines/content_block_manager/app/views/content_block_manager/content_block/editions/workflow/review_links.html.erb b/lib/engines/content_block_manager/app/views/content_block_manager/content_block/editions/workflow/review_links.html.erb index 10abdeb21f4..0692f45f7e6 100644 --- a/lib/engines/content_block_manager/app/views/content_block_manager/content_block/editions/workflow/review_links.html.erb +++ b/lib/engines/content_block_manager/app/views/content_block_manager/content_block/editions/workflow/review_links.html.erb @@ -9,6 +9,14 @@ <p class="govuk-body">The new <%= @content_block_document.block_type.humanize.downcase %> will appear on the following content after you publish the change.</p> +<%= + render( + ContentBlockManager::ContentBlock::Document::Show::HostEditionsRollupComponent.new( + rollup: @host_content_items.rollup, + ), + ) +%> + <div class="govuk-grid-row"> <div class="govuk-grid-column-full"> <%= render( diff --git a/lib/engines/content_block_manager/features/edit_object.feature b/lib/engines/content_block_manager/features/edit_object.feature index f301bd041c0..1550e96c2cc 100644 --- a/lib/engines/content_block_manager/features/edit_object.feature +++ b/lib/engines/content_block_manager/features/edit_object.feature @@ -18,6 +18,7 @@ Feature: Edit a content object And I should see a back link to the document page When I fill out the form Then I am shown where the changes will take place + And I see the rollup data for the dependent content And I should see a back link to the edit page When I save and continue Then I am asked when I want to publish the change @@ -37,6 +38,7 @@ Feature: Edit a content object Then I should see the edit form When I fill out the form Then I am shown where the changes will take place + And I see the rollup data for the dependent content And I click cancel Then I should be taken back to the document page And no draft Content Block Edition has been created @@ -48,6 +50,7 @@ Feature: Edit a content object Then I should see the edit form When I fill out the form Then I am shown where the changes will take place + And I see the rollup data for the dependent content When I save and continue Then I am asked when I want to publish the change And I click cancel @@ -101,5 +104,6 @@ Feature: Edit a content object When I revisit the edit page And I fill out the form Then I am shown where the changes will take place + And I see the rollup data for the dependent content When I click on the first host document Then the preview page opens in a new tab diff --git a/lib/engines/content_block_manager/features/step_definitions/content_block_manager_steps.rb b/lib/engines/content_block_manager/features/step_definitions/content_block_manager_steps.rb index f8a9a1b492b..47b77fd7d7f 100644 --- a/lib/engines/content_block_manager/features/step_definitions/content_block_manager_steps.rb +++ b/lib/engines/content_block_manager/features/step_definitions/content_block_manager_steps.rb @@ -450,10 +450,13 @@ def should_show_edit_form_for_email_address_content_block(document_title, email_ } end + @rollup = build(:rollup).to_h + stub_publishing_api_has_embedded_content_for_any_content_id( results: @dependent_content, total: @dependent_content.length, order: ContentBlockManager::GetHostContentItems::DEFAULT_ORDER, + rollup: @rollup, ) end @@ -466,6 +469,17 @@ def should_show_edit_form_for_email_address_content_block(document_title, email_ end end +Then(/^I (should )?see the rollup data for the dependent content$/) do |_should| + @rollup.keys.each do |k| + within ".rollup-details__rollup-metric.#{k}" do + assert_text k.to_s.titleize + within ".gem-c-glance-metric__figure" do + assert_text @rollup[k] + end + end + end +end + Then(/^I should see an error prompting me to choose an object type$/) do assert_text "You must select a block type" end diff --git a/lib/engines/content_block_manager/features/view_object.feature b/lib/engines/content_block_manager/features/view_object.feature index a8dc0739a5e..bebd5c113a2 100644 --- a/lib/engines/content_block_manager/features/view_object.feature +++ b/lib/engines/content_block_manager/features/view_object.feature @@ -19,6 +19,7 @@ Feature: View a content object When I visit the Content Block Manager home page And I click to view the document Then I should see the dependent content listed + And I should see the rollup data for the dependent content @javascript Scenario: GDS Editor can copy embed code diff --git a/lib/engines/content_block_manager/test/components/content_block/document/show/host_editions_rollup_component_test.rb b/lib/engines/content_block_manager/test/components/content_block/document/show/host_editions_rollup_component_test.rb new file mode 100644 index 00000000000..d6828019e7b --- /dev/null +++ b/lib/engines/content_block_manager/test/components/content_block/document/show/host_editions_rollup_component_test.rb @@ -0,0 +1,40 @@ +require "test_helper" + +class ContentBlockManager::ContentBlock::Document::Show::HostEditionsRollupComponentTest < ViewComponent::TestCase + extend Minitest::Spec::DSL + + let(:described_class) { ContentBlockManager::ContentBlock::Document::Show::HostEditionsRollupComponent } + + it "returns rolled up data with small numbers" do + rollup = build(:rollup, views: 12, locations: 2, instances: 3, organisations: 1) + + render_inline(described_class.new(rollup:)) + + assert_selector ".rollup-details__rollup-metric.views .gem-c-glance-metric__heading", text: "Views" + assert_selector ".rollup-details__rollup-metric.views .gem-c-glance-metric__figure", text: "12" + + assert_selector ".rollup-details__rollup-metric.locations .gem-c-glance-metric__heading", text: "Locations" + assert_selector ".rollup-details__rollup-metric.locations .gem-c-glance-metric__figure", text: "2" + + assert_selector ".rollup-details__rollup-metric.instances .gem-c-glance-metric__heading", text: "Instances" + assert_selector ".rollup-details__rollup-metric.instances .gem-c-glance-metric__figure", text: "3" + + assert_selector ".rollup-details__rollup-metric.organisations .gem-c-glance-metric__heading", text: "Organisations" + assert_selector ".rollup-details__rollup-metric.organisations .gem-c-glance-metric__figure", text: "1" + end + + it "returns rolled up data with larger numbers" do + rollup = build(:rollup, views: 12_000_000, locations: 15_000) + + render_inline(described_class.new(rollup:)) + + assert_selector ".rollup-details__rollup-metric.views .gem-c-glance-metric__heading", text: "Views" + assert_selector ".rollup-details__rollup-metric.views .gem-c-glance-metric__figure", text: "12" + assert_selector ".rollup-details__rollup-metric.views .gem-c-glance-metric__display-label", text: "m" + assert_selector ".rollup-details__rollup-metric.views .gem-c-glance-metric__explicit-label", text: "Million" + + assert_selector ".rollup-details__rollup-metric.locations .gem-c-glance-metric__figure", text: "15" + assert_selector ".rollup-details__rollup-metric.locations .gem-c-glance-metric__display-label", text: "k" + assert_selector ".rollup-details__rollup-metric.locations .gem-c-glance-metric__explicit-label", text: "Thousand" + end +end diff --git a/lib/engines/content_block_manager/test/factories/host_content_items.rb b/lib/engines/content_block_manager/test/factories/host_content_items.rb index 12c33f4a3ec..ecef943063b 100644 --- a/lib/engines/content_block_manager/test/factories/host_content_items.rb +++ b/lib/engines/content_block_manager/test/factories/host_content_items.rb @@ -3,11 +3,27 @@ total_pages { 1 } total { 10 } items { build_list(:host_content_item, 10) } + rollup { build(:rollup) } initialize_with do new(total_pages:, total:, - items:) + items:, + rollup:) + end + end + + factory :rollup, class: "ContentBlockManager::HostContentItems::Rollup" do + views { Random.rand(0..10) } + locations { Random.rand(0..10) } + instances { Random.rand(0..10) } + organisations { Random.rand(0..10) } + + initialize_with do + new(views:, + locations:, + instances:, + organisations:) end end end diff --git a/lib/engines/content_block_manager/test/unit/app/models/host_content_items_test.rb b/lib/engines/content_block_manager/test/unit/app/models/host_content_items_test.rb index 04a3613f139..6c158a1b2aa 100644 --- a/lib/engines/content_block_manager/test/unit/app/models/host_content_items_test.rb +++ b/lib/engines/content_block_manager/test/unit/app/models/host_content_items_test.rb @@ -6,7 +6,8 @@ class ContentBlockManager::HostContentItemsTest < ActiveSupport::TestCase let(:items) { build_list(:host_content_item, 5) } let(:total) { 12 } let(:total_pages) { 2 } - let(:host_content_items) { build(:host_content_items, items:, total:, total_pages:) } + let(:rollup) { build(:rollup) } + let(:host_content_items) { build(:host_content_items, items:, total:, total_pages:, rollup:) } it "delegates array methods to items" do ([].methods - Object.methods).each do |method| diff --git a/lib/engines/content_block_manager/test/unit/app/services/get_host_content_items_test.rb b/lib/engines/content_block_manager/test/unit/app/services/get_host_content_items_test.rb index 5d00aa1f4a8..e81a03aa06b 100644 --- a/lib/engines/content_block_manager/test/unit/app/services/get_host_content_items_test.rb +++ b/lib/engines/content_block_manager/test/unit/app/services/get_host_content_items_test.rb @@ -9,11 +9,14 @@ class ContentBlockManager::GetHostContentItemsTest < ActiveSupport::TestCase let(:host_content_id) { SecureRandom.uuid } + let(:rollup) { build(:rollup) } + let(:response_body) do { "content_id" => SecureRandom.uuid, "total" => 111, "total_pages" => 12, + "rollup" => rollup.to_h, "results" => [ { "title" => "foo", @@ -36,7 +39,7 @@ class ContentBlockManager::GetHostContentItemsTest < ActiveSupport::TestCase end setup do - stub_publishing_api_has_embedded_content(content_id: target_content_id, total: 111, total_pages: 12, results: response_body["results"], order: ContentBlockManager::GetHostContentItems::DEFAULT_ORDER) + stub_publishing_api_has_embedded_content(content_id: target_content_id, total: 111, total_pages: 12, results: response_body["results"], order: ContentBlockManager::GetHostContentItems::DEFAULT_ORDER, rollup: response_body["rollup"]) end describe "#items" do @@ -105,6 +108,11 @@ class ContentBlockManager::GetHostContentItemsTest < ActiveSupport::TestCase assert_equal result.total, response_body["total"] assert_equal result.total_pages, response_body["total_pages"] + assert_equal result.rollup.views, rollup.views + assert_equal result.rollup.locations, rollup.locations + assert_equal result.rollup.instances, rollup.instances + assert_equal result.rollup.organisations, rollup.organisations + assert_equal result[0].title, response_body["results"][0]["title"] assert_equal result[0].base_path, response_body["results"][0]["base_path"] assert_equal result[0].document_type, response_body["results"][0]["document_type"]