Skip to content

Commit

Permalink
Merge pull request #9754 from alphagov/content-modelling/688-pull-in-…
Browse files Browse the repository at this point in the history
…when-content-has-been-updated-by-an-update-to-a-content-block-within-publishing-apps

(688) Add content block updates to a document's timeline
  • Loading branch information
pezholio authored Jan 6, 2025
2 parents 61be985 + cb2fa03 commit eccb612
Show file tree
Hide file tree
Showing 32 changed files with 1,093 additions and 333 deletions.
20 changes: 20 additions & 0 deletions app/assets/stylesheets/admin/views/_host-content-update-event.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
.app-view-editions-host-content-update-event-entry {
&__list-item {
margin-bottom: govuk-spacing(4);
}

&__detail {
margin-top: govuk-spacing(0);
margin-bottom: govuk-spacing(0);
}

&__heading {
margin-bottom: govuk-spacing(1);
}

&__datetime {
margin-top: govuk-spacing(0);
margin-bottom: govuk-spacing(0);
color: $govuk-secondary-text-colour;
}
}
1 change: 1 addition & 0 deletions app/assets/stylesheets/application.scss
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ $govuk-page-width: 1140px;
@import "./admin/views/filter";
@import "./admin/views/govspeak-help";
@import "./admin/views/groups-index";
@import "./admin/views/host-content-update-event";
@import "./admin/views/historical-accounts-index";
@import "./admin/views/organisations-index";
@import "./admin/views/organisations-edit";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

<% if compare_with_previous_version? %>
<p class="govuk-body govuk-!-margin-bottom-0 govuk-!-margin-top-0">
<%= link_to "[Compare with previous version]", diff_admin_edition_path(@edition, audit_trail_entry_id: entry.version.item_id), class: "govuk-link" %>
<%= link_to "[Compare with previous version]", diff_admin_edition_path(@edition, audit_trail_entry_id: entry.item_id), class: "govuk-link" %>
</p>
<% end %>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@ def time
end

def compare_with_previous_version?
entry.action == "published" && edition.id != entry.version.item_id
entry.action == "published" && edition.id != entry.item_id
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ def entries_on_previous_editions
def render_entry(entry)
if entry.is_a?(EditorialRemark)
render(Admin::Editions::EditorialRemarkComponent.new(editorial_remark: entry))
elsif entry.is_a?(HostContentUpdateEvent)
render(Admin::Editions::HostContentUpdateEventComponent.new(entry))
else
render(Admin::Editions::AuditTrailEntryComponent.new(entry:, edition:))
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<div class="app-view-editions-host-content-update-event-entry__list-item">
<h4 class="govuk-heading-s app-view-editions-host-content-update-event-entry__heading">Content Block Update</h4>

<p class="govuk-body app-view-editions-host-content-update-event-entry__detail">
<%= activity %>
</p>

<p class="govuk-body-s app-view-editions-host-content-update-event-entry__datetime">
<%= time %> by <%= actor %>
</p>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
class Admin::Editions::HostContentUpdateEventComponent < ViewComponent::Base
include ApplicationHelper

def initialize(event)
@event = event
end

private

attr_reader :event

def activity
"#{event.content_title.strip} updated"
end

def time
absolute_time(event.created_at)
end

def actor
event.author ? linked_author(event.author, class: "govuk-link") : "User (removed)"
end
end
45 changes: 45 additions & 0 deletions app/decorators/document/paginated_timeline/version_decorator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
class Document::PaginatedTimeline::VersionDecorator < SimpleDelegator
def initialize(version, is_first_edition: false, previous_version: nil)
@is_first_edition = is_first_edition
@preloaded_previous_version = previous_version
super(version)
end

def ==(other)
self.class == other.class &&
id == other.id &&
action == other.action
end

def actor
user
end

def action
case event
when "create"
@is_first_edition ? "created" : "editioned"
else
previous_version&.state != state ? state : "updated"
end
end

def is_for_newer_edition?(edition)
item_id > edition.id
end

def is_for_current_edition?(edition)
item_id == edition.id
end

def is_for_older_edition?(edition)
item_id < edition.id
end

private

def previous_version
# we can avoid n+1 queries by using our preloaded_prev_version
@previous_version ||= @preloaded_previous_version || previous
end
end
25 changes: 25 additions & 0 deletions app/models/document.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,31 @@ def self.at_slug(document_types, slug)
find_by(document_type: document_types, slug:)
end

def remarks_by_ids(remark_ids)
editorial_remarks.where(id: remark_ids).index_by(&:id)
end

def active_edition_versions
edition_versions.where.not(state: "superseded")
end

def decorated_edition_versions_by_ids(version_ids)
versions = active_edition_versions.where(id: version_ids)

versions.map.with_index { |version, index|
version = Document::PaginatedTimeline::VersionDecorator.new(
version,
is_first_edition: version.item_id == first_edition_id,
previous_version: versions[index - 1],
)
[version.id, version]
}.to_h
end

def first_edition_id
@first_edition_id ||= editions.pick(:id)
end

def similar_slug_exists?
scope = Document.where(document_type:)
sequence_separator = friendly_id_config.sequence_separator
Expand Down
62 changes: 38 additions & 24 deletions app/models/document/paginated_timeline.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,23 @@ def initialize(document:, page:, only: nil)
def entries
@entries ||= begin
raw_entries = query.raw_entries
remarks = query.remarks
versions = query.versions
remarks = document.remarks_by_ids(query.remark_ids)
versions = document.decorated_edition_versions_by_ids(query.version_ids)

raw_entries.map do |entry|
versions_and_remarks = raw_entries.map do |entry|
case entry.model
when "Version"
versions.fetch(entry.id)
when "EditorialRemark"
remarks.fetch(entry.id)
end
end

if only.present?
versions_and_remarks
else
[*versions_and_remarks, *host_content_update_events].sort_by(&:created_at).reverse!
end
end
end

Expand All @@ -29,33 +35,15 @@ def query
end

def entries_on_newer_editions(edition)
@entries_on_newer_editions ||= entries.select do |entry|
if entry.is_a?(EditorialRemark)
entry.edition_id > edition.id
else
entry.version.item_id > edition.id
end
end
entries.select { |e| e.is_for_newer_edition?(edition) }
end

def entries_on_current_edition(edition)
@entries_on_current_edition ||= entries.select do |entry|
if entry.is_a?(EditorialRemark)
entry.edition_id == edition.id
else
entry.version.item_id == edition.id
end
end
entries.select { |e| e.is_for_current_edition?(edition) }
end

def entries_on_previous_editions(edition)
@entries_on_previous_editions ||= entries.select do |entry|
if entry.is_a?(EditorialRemark)
entry.edition_id < edition.id
else
entry.version.item_id < edition.id
end
end
entries.select { |e| e.is_for_older_edition?(edition) }
end

def total_count
Expand Down Expand Up @@ -89,4 +77,30 @@ def prev_page
false
end
end

private

def host_content_update_events
return [] if query.raw_entries.empty?

@host_content_update_events ||= HostContentUpdateEvent.all_for_date_window(
document:,
from: date_window.last,
to: date_window.first,
)
end

def date_window
@date_window ||= begin
start = page == 1 ? Time.zone.now : query.raw_entries.first.created_at
ends = next_page_entries ? next_page_entries.first.created_at : query.raw_entries.last.created_at
(start.to_time.round.utc..ends.to_time.round.utc)
end
end

def next_page_entries
if next_page
Document::PaginatedTimelineQuery.new(document:, page: next_page, only:).raw_entries
end
end
end
8 changes: 8 additions & 0 deletions app/models/edition.rb
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,14 @@ def can_set_previously_published?
true
end

def superseded_at
versions.find { |v| v.state == "superseded" }&.created_at
end

def published_at
versions.find { |v| v.state == "published" }&.created_at
end

def government
if government_id.present?
Government.find(government_id)
Expand Down
12 changes: 12 additions & 0 deletions app/models/editorial_remark.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,16 @@ class EditorialRemark < ApplicationRecord
belongs_to :author, class_name: "User"

validates :edition, :body, :author, presence: true

def is_for_newer_edition?(edition)
edition_id > edition.id
end

def is_for_current_edition?(edition)
edition_id == edition.id
end

def is_for_older_edition?(edition)
edition_id < edition.id
end
end
34 changes: 34 additions & 0 deletions app/models/host_content_update_event.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
class HostContentUpdateEvent < Data.define(:author, :created_at, :content_id, :content_title)
def self.all_for_date_window(document:, from:, to:)
events = Services.publishing_api.get_events_for_content_id(document.content_id, {
action: "HostContentUpdateJob",
from:,
to:,
})

events.map do |event|
HostContentUpdateEvent.new(
author: get_user_for_uuid(event["payload"]["source_block"]["updated_by_user_uid"]),
created_at: Time.zone.parse(event["created_at"]),
content_id: event["payload"]["source_block"]["content_id"],
content_title: event["payload"]["source_block"]["title"],
)
end
end

def is_for_newer_edition?(edition)
edition.superseded? && created_at.after?(edition.superseded_at)
end

def is_for_current_edition?(edition)
edition.published_at && created_at.after?(edition.published_at) && !is_for_newer_edition?(edition)
end

def is_for_older_edition?(edition)
!is_for_newer_edition?(edition) && !is_for_current_edition?(edition)
end

def self.get_user_for_uuid(uuid)
User.find_by(uid: uuid)
end
end
45 changes: 0 additions & 45 deletions app/presenters/queries/version_presenter.rb

This file was deleted.

Loading

0 comments on commit eccb612

Please sign in to comment.