Skip to content

Commit ae0bcc7

Browse files
committed
Latest WIP
1 parent dc5227d commit ae0bcc7

7 files changed

Lines changed: 143 additions & 45 deletions

File tree

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
module ConfigurableContentBlocks
2+
class ArrayOfHashes
3+
def to_partial_path
4+
"admin/configurable_content_blocks/array_of_hashes"
5+
end
6+
7+
8+
def publishing_api_payload(schema, content)
9+
return [] if content.blank?
10+
11+
social_media_items = content.is_a?(Hash) ? content.values : Array(content)
12+
social_media_items.filter_map do |item|
13+
next if item["_destroy"] == "1"
14+
build_api_output(schema, item)
15+
end
16+
end
17+
18+
private
19+
20+
21+
def build_api_output(schema, item)
22+
properties = schema.dig("items", "properties") || {}
23+
output = {}
24+
25+
properties.each do |field, field_schema|
26+
value = item[field]
27+
key = (field_schema["output_key"] || field).to_sym
28+
output[key] = value.present? ? value : nil
29+
end
30+
31+
output.compact
32+
end
33+
end
34+
end

app/models/configurable_content_blocks/factory.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ def build_block(block)
1212
"image_select" => ->(page) { ConfigurableContentBlocks::ImageSelect.new(page.valid_images) },
1313
"lead_image_select" => ->(page) { ConfigurableContentBlocks::LeadImageSelect.new(page.valid_lead_images, default_lead_image: page.default_lead_image, placeholder_image_url: page.placeholder_image_url) },
1414
"default_object" => ->(_page) { ConfigurableContentBlocks::DefaultObject.new(self) },
15+
"array_of_hashes" => ->(_page) { ConfigurableContentBlocks::ArrayOfHashes.new },
1516
}.freeze
1617

1718
raise "Block #{block} is not defined" if blocks[block].nil?
@@ -35,7 +36,7 @@ def blocks
3536
"default" => ->(_page) { ConfigurableContentBlocks::DefaultObject.new(self) },
3637
},
3738
"array" => {
38-
"social_media_accounts" => ->(_page) { ConfigurableContentBlocks::SocialMediaAccounts.new },
39+
"hash" => ->(_page) { ConfigurableContentBlocks::ArrayOfHashes.new },
3940
},
4041
"date" => {
4142
"default" => ->(_page) { ConfigurableContentBlocks::DefaultDate.new },

app/models/configurable_content_blocks/social_media_accounts.rb

Lines changed: 0 additions & 27 deletions
This file was deleted.

app/models/configurable_document_types/topical_event.json

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,6 @@
4242
"type": "string",
4343
"output_key": "href"
4444
}
45-
},
46-
"computed": {
47-
"title": {
48-
"transform": "social_media_service_display_name",
49-
"from": "social_media_service_id"
50-
}
5145
}
5246
}
5347
}

app/presenters/publishing_api/payload_builder/block_content.rb

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,37 @@ def lead_image(attribute)
8080
def string(attribute)
8181
item.block_content&.public_send(attribute)
8282
end
83+
84+
def array_of_hashes(attribute)
85+
content = item.block_content&.public_send(attribute)
86+
return [] if content.blank?
87+
88+
content.map { |item| process_social_media_item(item) }.compact
89+
end
90+
91+
private
92+
93+
def process_social_media_item(item)
94+
hash = case item
95+
when Hash
96+
item.transform_keys(&:to_sym)
97+
when Array
98+
{
99+
social_media_service_id: item[0],
100+
url: item[1],
101+
title: item[2] || ''
102+
}
103+
else
104+
return nil
105+
end
106+
107+
service = SocialMediaService.find_by(id: hash[:social_media_service_id])
108+
{
109+
service_type: service&.name&.downcase || 'other',
110+
href: hash[:url].to_s,
111+
title: hash[:title] || ''
112+
}
113+
end
83114
end
84115
end
85116
end

app/presenters/publishing_api/topical_event_presenter.rb

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def details
4242
details[:start_date] = item.start_date.rfc3339 if item.start_date
4343
details[:end_date] = item.end_date.rfc3339 if item.end_date
4444
details[:ordered_featured_documents] = ordered_featured_documents
45-
details[:social_media_links] = social_media_links
45+
details[:social_media_links] = item.block_content.social_media_links
4646
details.merge!(PayloadBuilder::EmphasisedOrganisations.for(item))
4747
end
4848
end
@@ -78,15 +78,5 @@ def ordered_featured_documents
7878
}
7979
end
8080
end
81-
82-
def social_media_links
83-
item.social_media_accounts.map do |social_media_account|
84-
{
85-
href: social_media_account.url,
86-
service_type: social_media_account.service_name.parameterize,
87-
title: social_media_account.display_name,
88-
}
89-
end
90-
end
9181
end
9282
end
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<% required ||= false
2+
content ||= []
3+
errors ||= []
4+
items = content.is_a?(Hash) ? content.values : Array(content)
5+
properties = schema.dig("items", "properties") || {}
6+
social_media_services = SocialMediaService.all
7+
8+
render_fields = ->(item, item_path, item_errors) do
9+
capture do
10+
properties.each do |key, prop|
11+
field_path = item_path.push(key)
12+
field_errors = item_errors.select { |e| e.attribute.to_s.end_with?(".#{key}") }
13+
14+
if prop["input_type"] == "social_media_service_select"
15+
concat(render("govuk_publishing_components/components/select", {
16+
id: field_path.form_control_id,
17+
label: prop["title"],
18+
name: "#{item_path.form_control_name}[#{key}]",
19+
heading_size: "s",
20+
options: [{ text: "", value: "" }] +
21+
social_media_services.map do |service|
22+
{
23+
text: service.name,
24+
value: service.id,
25+
selected: item[key].to_s == service.id.to_s,
26+
}
27+
end,
28+
full_width: true,
29+
error_items: field_errors.map { |e| { text: e.message } },
30+
}))
31+
else
32+
concat(render("govuk_publishing_components/components/input", {
33+
id: field_path.form_control_id,
34+
label: { text: prop["title"] },
35+
name: "#{item_path.form_control_name}[#{key}]",
36+
value: item[key],
37+
error_items: field_errors.map { |e| { text: e.message } },
38+
}))
39+
end
40+
end
41+
end
42+
end %>
43+
44+
<%= render "govuk_publishing_components/components/fieldset", {
45+
legend_text: "#{schema['title']}#{required ? ' (required)' : ''}",
46+
heading_size: "l",
47+
} do %>
48+
<div class="app-c-array-of-hashes">
49+
<%= render "govuk_publishing_components/components/add_another", {
50+
fieldset_legend: "Account",
51+
add_button_text: "Add account",
52+
empty_fields: true,
53+
items: items.each_with_index.filter_map do |item, index|
54+
next if item["_destroy"] == "1"
55+
56+
item_path = path.push(index.to_s)
57+
item_errors = errors.select { |e| e.attribute.to_s.start_with?(item_path.validation_error_attribute) }
58+
59+
{
60+
fields: render_fields.call(item, item_path, item_errors),
61+
destroy_checkbox: render("govuk_publishing_components/components/checkboxes", {
62+
name: "#{item_path.form_control_name}[_destroy]",
63+
items: [{ label: "Remove", value: "1" }],
64+
}),
65+
}
66+
end,
67+
empty: render_fields.call({}, path.push(items.length.to_s), []),
68+
} %>
69+
</div>
70+
<style>
71+
.app-c-array-of-hashes .js-add-another__add-button {
72+
margin-top: 20px;
73+
}
74+
</style>
75+
<% end %>

0 commit comments

Comments
 (0)