Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion app/controllers/admin/edition_images_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,11 @@ def create
@images.each { |image| @edition.images.delete(image) }
end

render :index
if @images.many?
render :index
else
redirect_to edit_admin_edition_image_path(@edition, @edition.images.first.id)
end
end

def create_image(image)
Expand Down
135 changes: 135 additions & 0 deletions app/controllers/admin/standard_edition_images_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
class Admin::StandardEditionImagesController < Admin::BaseController
before_action :find_edition
before_action :enforce_permissions!

def index; end

def confirm_destroy; end

def destroy
filename = image.image_data.carrierwave_image
image.destroy!
@edition.update_lead_image if @edition.can_have_custom_lead_image?
PublishingApiDocumentRepublishingWorker.perform_async(@edition.document_id, false)

redirect_to admin_edition_images_path(@edition), notice: "#{filename} has been deleted"
end

def update
image.assign_attributes(image_params)

if image_data_params["crop_data"].present?
image_data = image.image_data
new_image_data = ImageData.new
new_image_data.to_replace_id = image_data.id
new_image_data.assign_attributes(image_data_params)
new_image_data.file.download! image_data.file.url
new_image_data.save!
image.image_data = new_image_data
end

image.image_data.validate_on_image = image

if image.save
PublishingApiDocumentRepublishingWorker.perform_async(@edition.document_id, false)
redirect_to admin_standard_edition_images_path(@edition), notice: "#{image.image_data.carrierwave_image} details updated"
else
render :edit
end
end

def create
@images = images_params.map { |image| build_image(image) }

if @images.empty?
flash.now.alert = "No images selected. Choose a valid JPEG, PNG, SVG or GIF."
elsif @images.all?(&:valid?)
@images.each(&:save!)
PublishingApiDocumentRepublishingWorker.perform_async(@edition.document_id, false)
flash.now.notice = "Images successfully uploaded"
else
# Remove images from @edition.images array, otherwise the view will render it in the 'Uploaded images' list
@images.each { |image| @edition.images.delete(image) }
end

if @images.many? || @images.first.id.nil?
render :index
else
redirect_to edit_admin_standard_edition_image_path(@edition, @images.first.id)
end
end

def build_image(image)
new_image = @edition.images.build

new_image.build_image_data(image["image_data"])

new_image.image_data.validate_on_image = new_image

# so that auth_bypass_id is discoverable by AssetManagerStorage
new_image.image_data.images << new_image

new_image
end

def edit
flash.now.notice = "The image is being processed. Try refreshing the page." unless image&.image_data&.original_uploaded?
end

private

def image_url
return unless image&.image_data&.original_uploaded?

image_data = image.image_data
unless image_data.file.cached?
image_data.file.download! image_data.file.url
end
img_data = Base64.strict_encode64(image_data.file.read)

"data:#{image_data.file.content_type};base64,#{img_data}"
end
helper_method :image_url

def image_kind_config
image.image_data.image_kind_config
end
helper_method :image_kind_config

def image
@image ||= find_image
end
helper_method :image

def find_image
@edition.images.find(params[:id]) if params[:id]
end

def find_edition
edition = StandardEdition.includes(images: :image_data).find(params[:standard_edition_id])
@edition = LocalisedModel.new(edition, edition.primary_locale)
end

def enforce_permissions!
case action_name
when "index"
enforce_permission!(:see, @edition)
when "edit", "update", "destroy", "confirm_destroy", "create"
enforce_permission!(:update, @edition)
else
raise Whitehall::Authority::Errors::InvalidAction, action_name
end
end

def images_params
params.fetch(:images, []).map { |image| image.permit(image_data: %i[file image_kind]) }
end

def image_data_params
params.fetch(:image, {}).fetch(:image_data, {}).permit(:file, :image_kind, crop_data: %i[x y width height])
end

def image_params
params.fetch(:image, {}).except(:image_data).permit(:caption, image_data: %i[crop_data file image_kind])
end
end
5 changes: 3 additions & 2 deletions app/helpers/admin/tabbed_nav_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,12 @@ def attachments_nav_items(edition, current_path)
end

def images_nav_items(edition, current_path)
images_path = edition.is_a?(StandardEdition) ? admin_standard_edition_images_path(edition) : admin_edition_images_path(edition)
[
{
label: sanitize("Images #{tag.span(edition.images.count, class: 'govuk-tag govuk-tag--grey') if edition.images.count.positive?}"),
href: admin_edition_images_path(edition),
current: current_path == admin_edition_images_path(edition),
href: images_path,
current: current_path == images_path,
},
]
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@
"publishing_api_schema_name": "news_article",
"publishing_api_document_type": "government_response",
"rendering_app": "frontend",
"images_enabled": true,
"images": {
"enabled": true
},
"send_change_history": true,
"file_attachments_enabled": true,
"organisations": null,
Expand Down
4 changes: 3 additions & 1 deletion app/models/configurable_document_types/history_page.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@
"publishing_api_schema_name": "history",
"publishing_api_document_type": "history",
"rendering_app": "frontend",
"images_enabled": true,
"images": {
"enabled": true
},
"send_change_history": false,
"organisations": ["af07d5a5-df63-4ddc-9383-6a666845ebe9"],
"backdating_enabled": false,
Expand Down
4 changes: 3 additions & 1 deletion app/models/configurable_document_types/news_story.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@
"publishing_api_schema_name": "news_article",
"publishing_api_document_type": "news_story",
"rendering_app": "frontend",
"images_enabled": true,
"images": {
"enabled": true
},
"send_change_history": true,
"file_attachments_enabled": true,
"organisations": null,
Expand Down
4 changes: 3 additions & 1 deletion app/models/configurable_document_types/press_release.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@
"publishing_api_schema_name": "news_article",
"publishing_api_document_type": "press_release",
"rendering_app": "frontend",
"images_enabled": true,
"images": {
"enabled": true
},
"send_change_history": true,
"file_attachments_enabled": true,
"organisations": null,
Expand Down
5 changes: 4 additions & 1 deletion app/models/configurable_document_types/topical_event.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,10 @@
"publishing_api_schema_name": "topical_event",
"publishing_api_document_type": "topical_event",
"rendering_app": "collections",
"images_enabled": false,
"images": {
"enabled": true,
"permitted_image_kinds": ["header", "logo"]
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will need to turn this into an object so that we can say whether or not users should be able to upload multiple images of each kind.

},
"send_change_history": true,
"file_attachments_enabled": false,
"organisations": null,
Expand Down
4 changes: 3 additions & 1 deletion app/models/configurable_document_types/world_news_story.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@
"publishing_api_schema_name": "news_article",
"publishing_api_document_type": "world_news_story",
"rendering_app": "frontend",
"images_enabled": true,
"images": {
"enabled": true
},
"send_change_history": true,
"file_attachments_enabled": true,
"organisations": null,
Expand Down
8 changes: 7 additions & 1 deletion app/models/standard_edition.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def locale_can_be_changed?
end

def allows_image_attachments?
type_instance.settings["images_enabled"]
type_instance.settings["images"]["enabled"]
end

def allows_file_attachments?
Expand Down Expand Up @@ -88,4 +88,10 @@ def world_location_association_required?
def is_in_valid_state_for_type_conversion?
%w[draft submitted rejected].include?(state)
end

def permitted_image_kinds
return super unless type_instance.settings["images"]["permitted_image_kinds"]

Whitehall.image_kinds.values.select { _1.permitted_uses.intersect?(type_instance.settings["images"]["permitted_image_kinds"]) }
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a bit ugly. Unfortunately the image kind config introduced during the landing page work does not put the usages at the root of the data structure. Instead it looks like aspect ratio -> usage -> versions (sizes). We can probably refactor this at a later date but it would mean changing landing pages. So perhaps when we convert landing pages to configurable documents is the time to do this.

end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<section class="govuk-grid-column-one-third">
<% if image.persisted? %>
<% if image_url %>
<img src="<%= image_url %>" alt="Image preview" class="app-view-edition-resource__preview govuk-!-margin-bottom-4">
<% else %>
<div class="govuk-!-margin-bottom-4">
<span class="govuk-tag govuk-tag--green">Processing</span>
</div>
<% end %>
<% end %>
<h2 class="govuk-heading-m">Image information</h2>
<ul class="govuk-list">
<% if image.bitmap? %>
<li><strong>Width: </strong><%= image.width %>px</li>
<li><strong>Height: </strong><%= image.height %>px</li>
<% end %>
<li><strong>Format: </strong><%= image.content_type %></li>
<li><strong>File name: </strong><%= image.filename %></li>
</ul>
</section>
37 changes: 37 additions & 0 deletions app/views/admin/standard_edition_images/_image_upload.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<%= form_tag(
admin_standard_edition_images_path(@edition),
multipart: true,
) do %>
<%= render "govuk_publishing_components/components/file_upload", {
label: {
text: "Upload a #{image_kind.display_name} image",
},
heading_level: 2,
heading_size: "l",
javascript: true,
multiple: true,
name: "images[][image_data][file]",
id: "edition_images_image_data_file",
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.'),
error_items: @new_image.present? ? errors_for(@new_image.errors, :"image_data.file") : nil,
accept: "image/png, image/jpeg, image/gif, image/svg+xml",
} %>

<%= hidden_field_tag("images[][image_data][image_kind]", image_kind.name) %>

<%= render "govuk_publishing_components/components/details", {
title: "You must use an SVG for charts and diagrams",
} do %>
SVGs allow users to magnify images without losing quality.
Find out <%= link_to "how to create an SVG file (opens in new tab)",
"https://www.gov.uk/guidance/how-to-publish-on-gov-uk/images-and-videos#creating-an-svg-file",
class: "govuk-link",
target: "_blank",
rel: "noopener" %>.
<% end %>

<%= render "govuk_publishing_components/components/button", {
text: "Upload",
margin_bottom: 10,
} %>
<% end %>
21 changes: 21 additions & 0 deletions app/views/admin/standard_edition_images/confirm_destroy.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<% content_for :context, @edition.title %>
<% content_for :page_title, "Delete image" %>
<% content_for :title, "Delete image" %>
<% content_for :title_margin_bottom, 6 %>

<div class="govuk-grid-row">
<section class="govuk-grid-column-two-thirds">
<%= form_tag [:admin, :standard_edition, :image], id: image, method: :delete do %>
<p class="govuk-body govuk-!-margin-bottom-7">Are you sure you want to delete <%= image.image_data.carrierwave_image %>?</p>

<div class="govuk-button-group govuk-!-margin-bottom-6">
<%= render "govuk_publishing_components/components/button", {
text: "Delete image",
destructive: true,
} %>

<%= link_to("Cancel", admin_standard_edition_images_path(@edition), class: "govuk-link govuk-link--no-visited-state") %>
</div>
<% end %>
</section>
</div>
54 changes: 54 additions & 0 deletions app/views/admin/standard_edition_images/edit.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<% content_for :context, @edition.title %>
<% content_for :page_title, "Edit image details" %>
<% content_for :title, "Edit image details" %>
<% content_for :title_margin_bottom, 6 %>

<div class="govuk-grid-row">

<section class="govuk-grid-column-two-thirds">
<%= form_tag [:admin, :standard_edition, :image], id: image, multipart: true, method: :patch do %>
<p class="govuk-body-lead">You can leave any image detail blank if you do not need it.</p>

<%= hidden_field_tag("image[image_data][image_kind]", image.image_data.image_kind) %>

<% if image.can_be_cropped? && image.image_data&.original_uploaded? %>
<%= render "components/image_cropper", {
name: "image[image_data][crop_data]",
src: image_url,
filename: image.filename,
type: image.content_type,
width: image_kind_config.valid_width,
height: image_kind_config.valid_height,
x: image.image_data.crop_data_x,
y: image.image_data.crop_data_y,
} %>
<% end %>

<%= render "govuk_publishing_components/components/textarea", {
label: {
text: "Caption and credit",
heading_size: "l",
},
name: "image[caption]",
textarea_id: "image_caption",
value: image.caption,
rows: 2,
hint: raw("Name a person in a photo or add image credit. <a class='govuk-link' href='https://www.gov.uk/guidance/content-design/images'>Read the image copyright standards</a>. The text appears next to the image."),
margin_bottom: 4,
} %>

<p class="govuk-body"><a href="https://www.gov.uk/guidance/content-design/images" class="govuk-link" target="_blank">Using informative and decorative images on GOV.UK (opens in new tab)</a></p>

<div class="govuk-button-group govuk-!-margin-bottom-6">
<%= render "govuk_publishing_components/components/button", {
text: "Save",
} %>

<%= link_to("Cancel", admin_standard_edition_images_path(@edition), class: "govuk-link govuk-link--no-visited-state") %>
</div>
<% end %>
</section>

<%= render "image_information" %>

</div>
Loading
Loading