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

content modelling/830 show changes to a content block #9842

Merged
merged 3 commits into from
Jan 27, 2025

Conversation

Harriethw
Copy link
Contributor

@Harriethw Harriethw commented Jan 24, 2025

  • add edition's field diff to content block versions

we want to show the changes that have been made to
a block when updating - this takes a snapshot of
the difference between the user generated fields
and saves them as a json blob, with the key being
the field name.

I'm hesitant to use json as it isn't typed, but I
explored [1] codifying the data structure
previously and it proved too complicated and
inefficient, especially as the fields need to be
displayed to the user in a certain order of
priority, and we don't know exactly what the
fields we're saving will be. By using the Data
class to show the shape of the items, this is
hopefully a halfway house. Shoving everything in a
json blob seems like a middle ground between just
calculating everything at run time and having a
genuine record of the change.

[1] #9838

  • Add content block changes table to timeline

As design
Screenshot 2025-01-24 at 16 56 02


⚠️ This repo is Continuously Deployed: make sure you follow the guidance ⚠️

Follow these steps if you are doing a Rails upgrade.

@Harriethw Harriethw changed the title content modelling/830 show changes 2 content modelling/830 show changes to a content block Jan 24, 2025
@Harriethw Harriethw force-pushed the content-modelling/830-show-changes-2 branch from 1ef6742 to 5b7ce20 Compare January 24, 2025 11:26
@Harriethw Harriethw requested a review from pezholio January 24, 2025 11:28
@Harriethw Harriethw marked this pull request as ready for review January 24, 2025 11:28
end
end

FIELD_DIFF = Data.define(:previous_value, :new_value)
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if you might be better having FIELD_DIFF as a separate class with a .all_for_document class method. That way you can test it in isolation a bit better, as well as breaking down the methods in field_diff a bit more. Something like:

class FieldDiff < Data.define(:previous_value, :new_value)
  def self.all_for_document
     # logic from `field_diff` goes here, maybe broken down into smaller methods
  end
end

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm also wondering if you could have a way of translating the JSON into a FieldDiff object, that way if there are any changes to the structure, you could handle that programatically, rather than having to deal with JSON objects that may have changed over time

Copy link
Contributor Author

@Harriethw Harriethw Jan 24, 2025

Choose a reason for hiding this comment

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

good shout about breaking out the logic, will take a look.

I'm also wondering if you could have a way of translating the JSON into a FieldDiff object

I was wondering if there was way to use jsonschema in some way - basically it should always follow this shape

{
  {field_key}: {
    "previous_value": string,
    "new_value": string,
  }
}

but with the field_key being unknown i don't how to say that in rails land 🤔

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe having an array of objects like this might be more predictable:

[
  { "key": string, "previous_value": string, "new_value": string }
]

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried the array part in the last approach but it's a nightmare to then try and work out the order and display it correctly on the front end...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

though maybe now we are doing the ordering in the audit_trail the frontend is less a problem, as long as the order was preserved when we iterate through to make the rows...

Copy link
Contributor

Choose a reason for hiding this comment

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

Could you add an "order" param to each object maybe?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Could you add an "order" param to each object maybe?
I think it would be a bit difficult to do that because we don't know beforehand what the keys could be that come out of the details blob, but maybe there's a way around that...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok I've had a go at your suggestions and think it's looking better 👍

@@ -34,4 +35,16 @@ def time_html(date_time)
lang: "en",
)
end

def table_rows(version)
Copy link
Contributor

Choose a reason for hiding this comment

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

This is loads better! 👍

@Harriethw Harriethw force-pushed the content-modelling/830-show-changes-2 branch from 5b7ce20 to 101b5e8 Compare January 24, 2025 16:57
Copy link
Contributor

@pezholio pezholio left a comment

Choose a reason for hiding this comment

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

This looks ace. Thanks for struggling through it all! A couple of minor comments, but I think it looks good overall 👍

field_diffs = []
previous_edition = edition.document.editions.includes(:edition_organisation, :organisation)[-2]
if previous_edition.title != edition.title
field_diffs.append(ContentBlockManager::ContentBlock::FieldDiff.new(field_name: "title", previous_value: previous_edition.title, new_value: edition.title))
Copy link
Contributor

Choose a reason for hiding this comment

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

You could probably just do new(...) here

Comment on lines 41 to 45
rows = []
version.field_diffs.each do |field|
rows.append([{ text: field["field_name"].humanize }, { text: field["previous_value"] }, { text: field["new_value"] }])
end
rows
Copy link
Contributor

Choose a reason for hiding this comment

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

You could probably just do map here:

Suggested change
rows = []
version.field_diffs.each do |field|
rows.append([{ text: field["field_name"].humanize }, { text: field["previous_value"] }, { text: field["new_value"] }])
end
rows
version.field_diffs.map do |field|
[
{ text: field["field_name"].humanize },
{ text: field["previous_value"] },
{ text: field["new_value"] },
]
end

(Added some linebreaks for readability too)

a list of these will be saved against the json column
`field_diffs` on a version. Because of the way these
need to be saved and iterated through (e.g. for one thing it's not a normal one to many relationship, we won't want to add to the list ever again), it's much easier and makes more sense for the column to remain json and we define the
data here.
we want to show the changes that have been made to
a block when updating - this takes a snapshot of
the difference between the user generated fields
and saves them as a json blob, with the key being
the field name.

I'm hesitant to use json as it isn't typed, but I
explored [1] codifying the data structure
previously and it proved too complicated and
inefficient, especially as the fields need to be
displayed to the user in a certain order of
priority, and we don't know exactly what the
fields we're saving will be. By using the Data
class to show the shape of the items, this is
hopefully a halfway house. Shoving everything in a
json blob seems like a middle ground between just
calculating everything at run time and having a
genuine record of the change.

[1] #9838
@Harriethw Harriethw force-pushed the content-modelling/830-show-changes-2 branch from 101b5e8 to d977e60 Compare January 24, 2025 17:28
@Harriethw
Copy link
Contributor Author

@pezholio thank you!! have made those suggestions. I don't think I'll be around to watch it go green so feel free to merge on Monday when I'm not in

@pezholio pezholio merged commit 4371d04 into main Jan 27, 2025
19 checks passed
@pezholio pezholio deleted the content-modelling/830-show-changes-2 branch January 27, 2025 08:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants