Skip to content

Commit 5a377fb

Browse files
Specify specific image kinds for editions
Rework the previous implementation of edition image partials to accept an image kind as a parameter. If the image kind supports a single upload then only show the upload form if no image has been uploaded. Otherwise show the default (unchanged) edition images view.
1 parent c950e8e commit 5a377fb

14 files changed

Lines changed: 242 additions & 50 deletions

File tree

app/components/admin/edition_images/uploaded_images_component.html.erb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<% if edition.configurable_document_type.present? %>
1+
<% if edition.configurable_document_type.present? && edition.allows_lead_image? %>
22
<%= render "govuk_publishing_components/components/heading", {
33
text: "Select a lead image",
44
font_size: "l",
Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
# frozen_string_literal: true
22

33
class Admin::EditionImages::UploadedImagesComponent < ViewComponent::Base
4-
def initialize(edition:)
4+
def initialize(edition:, image_kind: Whitehall.image_kinds.fetch("default"))
55
@edition = edition
6+
@image_kind = image_kind
67
end
78

89
private
910

1011
attr_reader :edition
1112

1213
def document_images
13-
return edition.images unless edition.can_have_custom_lead_image?
14+
edition_images = edition.images.select { |image| Whitehall.image_kinds.fetch(image.image_data.image_kind) == @image_kind }
1415

15-
edition.images - [edition.lead_image].compact
16+
return edition_images unless edition.can_have_custom_lead_image?
17+
18+
edition_images - [edition.lead_image].compact
1619
end
1720
end

app/controllers/admin/edition_images_controller.rb

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,7 @@ def update
4141
def create
4242
@images = images_params.map { |image| create_image(image) }
4343

44-
if @images.empty?
45-
flash.now.alert = "No images selected. Choose a valid JPEG, PNG, SVG or GIF."
46-
elsif @images.all?(&:valid?)
44+
if @images.all?(&:valid?)
4745
@images.each(&:save)
4846
@edition.update_lead_image if @edition.can_have_custom_lead_image?
4947
PublishingApiDocumentRepublishingWorker.perform_async(@edition.document_id, false)
@@ -53,7 +51,11 @@ def create
5351
@images.each { |image| @edition.images.delete(image) }
5452
end
5553

56-
render :index
54+
if @images.count == 1 && @images.first.valid?
55+
redirect_to edit_admin_edition_image_path(@edition, @images.first.id)
56+
else
57+
render :index
58+
end
5759
end
5860

5961
def create_image(image)
@@ -119,7 +121,7 @@ def enforce_permissions!
119121
end
120122

121123
def images_params
122-
params.fetch(:images, []).map { |image| image.permit(image_data: %i[file]) }
124+
params.fetch(:images, []).map { |image| image.permit(image_data: %i[file image_kind]) }
123125
end
124126

125127
def image_data_params

app/models/concerns/edition/images.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,11 @@ def process_associations_after_save(edition)
2121
end
2222

2323
included do
24-
has_many :images, foreign_key: "edition_id", dependent: :destroy
24+
has_many :images, foreign_key: "edition_id", dependent: :destroy do
25+
def of_kind(image_kind)
26+
joins(:image_data).where(image_data: { image_kind: image_kind })
27+
end
28+
end
2529

2630
accepts_nested_attributes_for :images, reject_if: :no_substantive_attributes?, allow_destroy: true
2731

app/models/edition.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,14 @@ def can_have_custom_lead_image?
433433
is_a?(Edition::CustomLeadImage)
434434
end
435435

436+
def allows_multiple_of_image_kind?(image_kind)
437+
image_kind == "govspeak_embed"
438+
end
439+
440+
def permitted_single_upload_image_kinds
441+
[]
442+
end
443+
436444
def images_have_unique_filenames?
437445
names = images.map(&:filename)
438446
names.uniq.length == names.length

app/models/image.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ class Image < ApplicationRecord
99

1010
accepts_nested_attributes_for :image_data
1111

12-
delegate :filename, :content_type, :width, :height, :bitmap?, :svg?, :can_be_cropped?, :requires_crop?, to: :image_data
12+
delegate :filename, :content_type, :width, :height, :bitmap?, :svg?, :can_be_cropped?, :requires_crop?, :image_kind, to: :image_data
1313

1414
default_scope -> { order(:id) }
1515

app/models/standard_edition.rb

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ def body
4343
block_content["body"]
4444
end
4545

46+
def lead_image
47+
block_content["image"]
48+
end
49+
4650
def body=(_)
4751
nil
4852
end
@@ -59,10 +63,24 @@ def locale_can_be_changed?
5963
translatable? && translations.size <= 1
6064
end
6165

66+
def allows_lead_image?
67+
type_instance.form["fields"]["image"].present?
68+
end
69+
6270
def allows_image_attachments?
6371
type_instance.settings["images"]["enabled"]
6472
end
6573

74+
def allows_multiple_of_image_kind?(image_kind)
75+
return if type_instance.settings["images"]["permitted_image_kinds"].blank?
76+
77+
type_instance_image_kind = type_instance.settings["images"]["permitted_image_kinds"].detect { |permitted_image_kind| permitted_image_kind["kind"] == image_kind }
78+
79+
return if type_instance_image_kind.blank?
80+
81+
type_instance_image_kind["multiple"]
82+
end
83+
6684
def allows_file_attachments?
6785
type_instance.settings["file_attachments_enabled"]
6886
end
@@ -99,6 +117,16 @@ def is_in_valid_state_for_type_conversion?
99117
%w[draft submitted rejected].include?(state)
100118
end
101119

120+
def permitted_single_upload_image_kinds
121+
Whitehall.image_kinds.values.select { _1.permitted_uses.intersect?(type_instance.settings["images"]["permitted_image_kinds"].reject { |image| image["multiple"] }.map { |image| image["kind"] }) }
122+
end
123+
124+
def permitted_image_kinds
125+
return super unless type_instance.settings["images"]["permitted_image_kinds"]
126+
127+
Whitehall.image_kinds.values.select { _1.permitted_uses.intersect?(type_instance.settings["images"]["permitted_image_kinds"].map { |image| image["kind"] }) }
128+
end
129+
102130
private
103131

104132
def string_for_slug

app/views/admin/edition_images/_image_upload.html.erb

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,29 @@
1+
<%
2+
image_kind ||= Whitehall.image_kinds.fetch("default")
3+
text = image_kind.permitted_uses.include?("govspeak_embed") ? "Upload an image" : "Upload #{image_kind.display_name} image"
4+
%>
5+
16
<%= form_tag(
27
admin_edition_images_path(@edition),
8+
id: "#{image_kind.name}_image_upload_form",
39
multipart: true,
410
) do %>
511
<%= render "govuk_publishing_components/components/file_upload", {
612
label: {
7-
text: "Upload an image",
13+
text:,
814
},
915
heading_level: 2,
1016
heading_size: "l",
1117
javascript: true,
12-
multiple: true,
18+
multiple: @edition.allows_multiple_of_image_kind?(image_kind.permitted_uses.first),
1319
name: "images[][image_data][file]",
1420
id: "edition_images_image_data_file",
1521
hint: raw('Images can be JPEG, PNG, SVG or GIF files. If you are uploading more than one image, <a class="govuk-link" href="https://www.gov.uk/guidance/how-to-publish-on-gov-uk/images-and-videos">read the image guidance</a> on using unique file names.'),
1622
error_items: @new_image.present? ? errors_for(@new_image.errors, :"image_data.file") : nil,
1723
accept: "image/png, image/jpeg, image/gif, image/svg+xml",
1824
} %>
1925

20-
<% if @edition.permitted_image_kinds.size == 1 %>
21-
<%= hidden_field_tag("image[image_data][image_kind]", @edition.permitted_image_kinds.first.name) %>
22-
<% else %>
23-
<%= render "govuk_publishing_components/components/radio", {
24-
heading: "What kind of image is this?",
25-
name: "image[image_data][image_kind]",
26-
items: @edition.permitted_image_kinds.map do |image_kind|
27-
{
28-
value: image_kind.name,
29-
text: image_kind.display_name,
30-
}
31-
end,
32-
} %>
33-
<% end %>
26+
<%= hidden_field_tag("images[][image_data][image_kind]", image_kind.name) %>
3427

3528
<%= render "govuk_publishing_components/components/details", {
3629
title: "You must use an SVG for charts and diagrams",

app/views/admin/edition_images/index.html.erb

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,32 @@
1010
items: secondary_navigation_tabs_items(@edition, request.path),
1111
} %>
1212

13-
<%= render "image_upload", edition: @edition %>
14-
<%= render Admin::EditionImages::UploadedImagesComponent.new(edition: @edition) %>
13+
<% @edition.permitted_single_upload_image_kinds.each do |image_kind| %>
14+
15+
<% images_of_image_kind = @edition.images.of_kind(image_kind.name) %>
16+
17+
<% if images_of_image_kind.count == 0 || @edition.allows_multiple_of_image_kind?(image_kind) %>
18+
<%= render "image_upload", edition: @edition, image_kind: %>
19+
<% end %>
20+
21+
<% if images_of_image_kind.count > 0 %>
22+
<%= render "govuk_publishing_components/components/heading", {
23+
text: "Uploaded #{image_kind.display_name} images",
24+
heading_level: 2,
25+
font_size: "l",
26+
margin_bottom: 2,
27+
} %>
28+
<ul id="uploaded_<%= image_kind.name %>_image_list" class="govuk-list">
29+
<% images_of_image_kind.each do |image| %>
30+
<%= render Admin::EditionImages::ImageComponent.new(edition: @edition, image: image, last_image: true) %>
31+
<% end %>
32+
</ul>
33+
<% end %>
34+
<% end %>
35+
36+
<% (@edition.permitted_image_kinds - @edition.permitted_single_upload_image_kinds).each do |image_kind| %>
37+
<%= render "image_upload", edition: @edition, image_kind: %>
38+
<%= render Admin::EditionImages::UploadedImagesComponent.new(edition: @edition, image_kind:) %>
39+
<% end %>
1540
</div>
1641
</div>

features/edition-images-javascript.feature

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,39 @@ Feature: Images tab on edit edition
1111
When I visit the images tab of the document with images
1212
Then I should see a list with 2 images
1313
When I upload a 960x960 image
14+
Then I should see the image cropper in the following edit screen
15+
When I update the image details and save
1416
Then I should see a list with 3 images
17+
Then I should not see that the image requires cropping
18+
19+
@javascript
20+
Scenario: Images uploaded with cropping required
21+
And a draft document with images exists
22+
When I visit the images tab of the document with images
23+
Then I should see a list with 2 images
24+
When I upload multiple images including a 960x960 image
25+
Then I should see a list with 4 images
1526
Then I should see that the image requires cropping
1627
When I click to edit the details of the image that needs to be cropped
28+
Then I should see the image cropper in the following edit screen
1729
When I update the image details and save
18-
Then I should not see that the image requires cropping
30+
Then I should see a list with 4 images
31+
Then I should not see that the image requires cropping
32+
33+
@javascript
34+
Scenario: Image uploaded with no cropping required
35+
And a draft publication "New Draft Publication" exists
36+
When I visit the images tab of the document "New Draft Publication"
37+
And I upload a 960x640 image
38+
Then I should not see the image cropper in the following edit screen
39+
When I update the image details and save
40+
Then I should see a list with 1 image
1941

2042
@javascript
2143
Scenario: Uploading a file with a duplicated filename
2244
When a draft document with images exists
2345
And I visit the images tab of the document with images
2446
And I upload a 960x960 image
47+
When I update the image details and save
2548
And I upload a 960x960 image
2649
Then I should get 1 error message

0 commit comments

Comments
 (0)