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

Ctskf 833 250113 #8041

Open
wants to merge 22 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
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
39 changes: 39 additions & 0 deletions app/controllers/documents_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,45 @@ def destroy
end
end

def upload
@document = Document.new(creator_id: current_user.id, document: params[:documents])

if @document.save_and_verify
render_success_response
else
render_error_response
end
end

def delete
# TODO: This does not do any checking to see if the document is owned by the current user
@document = Document.find(params[:delete])

@document.destroy

render json: { file: { filename: params[:delete] } }
end

def render_success_response
render json: {
file: {
originalname: @document.document.filename,
filename: @document.id
},
success: {
messageHtml: "#{@document.document.filename} uploaded"
}
}, status: :created
end

def render_error_response
render json: {
error: {
message: "#{@document.document.filename} #{@document.errors[:document].join(', ')}"
}
}, status: :accepted
end

private

def document
Expand Down
28 changes: 20 additions & 8 deletions app/controllers/messages_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,8 @@ class MessagesController < ApplicationController
def create
@message = Message.new(message_params.merge(sender_id: current_user.id))

@notification = if @message.save
{ notice: 'Message successfully sent' }
else
{ alert: 'Message not sent: ' + @message.errors.full_messages.join(', ') }
end
attach_documents
save_message

respond_to do |format|
format.js
Expand All @@ -35,9 +32,24 @@ def create
end

def download_attachment
raise 'No attachment present on this message' unless message.attachment.attached?
raise 'No attachment present on this message' unless message.attachments.attached?

redirect_to message.attachments.first.blob.url(disposition: 'attachment'), allow_other_host: true
end

redirect_to message.attachment.blob.url(disposition: 'attachment'), allow_other_host: true
def attach_documents
documents = Document.where(id: params[:message][:document_ids])
documents.each do |doc|
@message.attachments.attach(doc.document.blob)
end
end

def save_message
@notification = if @message.save
{ notice: 'Message successfully sent' }
else
{ alert: 'Message not sent: ' + @message.errors.full_messages.join(', ') }
end
end

private
Expand All @@ -59,7 +71,7 @@ def message_params
params.require(:message).permit(
:sender_id,
:claim_id,
:attachment,
:attachments,
:body,
:claim_action,
:written_reasons_submitted
Expand Down
10 changes: 5 additions & 5 deletions app/interfaces/api/entities/document.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,20 @@ class Document < BaseEntity

private

def attachment
object.is_a?(ActiveStorage::Attachment) ? object : object.attachment
def attachments
object.is_a?(ActiveStorage::Attachment) ? object : object.attachments
end

def url
attachment.blob.url(disposition: 'attachment') if attachment.attached?
attachments.first.blob.url(disposition: 'attachment') if attachments.attached?
end

def file_name
attachment.filename if attachment.attached?
attachments.first.filename if attachments.attached?
end

def size
attachment.byte_size if attachment.attached?
attachments.first.byte_size if attachments.attached?
end
end
end
Expand Down
4 changes: 2 additions & 2 deletions app/interfaces/api/entities/message.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ class Message < BaseEntity
expose :created_at, format_with: :utc
expose :sender_uuid
expose :body
expose :attachment,
expose :attachments,
as: :document,
using: API::Entities::Document,
if: ->(instance, _opts) { instance.attachment.present? }
if: ->(instance, _opts) { instance.attachments.present? }

private

Expand Down
6 changes: 4 additions & 2 deletions app/models/ability.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ def external_user(persona)

def case_worker_admin(persona)
can %i[index show update archived], Claim::BaseClaim
can %i[upload delete], Document
can %i[show download], Document
can %i[index new create], CaseWorker
can %i[show show_message_controls edit change_password update_password update destroy], CaseWorker
Expand All @@ -62,6 +63,7 @@ def case_worker(persona)
claim.case_workers.include?(persona)
end
can_administer_any_provider if persona.roles.include?('provider_management')
can %i[upload delete], Document
can %i[show download], Document
can %i[index feedback], CourtData
can_manage_own_password(persona)
Expand All @@ -86,7 +88,7 @@ def can_administer_any_claim_in_provider(persona)
end

def can_administer_documents_in_provider(persona)
can %i[index create], Document
can %i[index create upload delete], Document

# NOTE: for destroy action, at least, the document may not be persisted/saved
can %i[show download destroy], Document do |document|
Expand Down Expand Up @@ -127,7 +129,7 @@ def can_manage_own_claims_of_class(persona, claim_klass)
end

def can_manage_own_documents(persona)
can %i[index create], Document
can %i[index create upload delete], Document

can %i[show download destroy], Document do |document|
if document.external_user_id.nil?
Expand Down
15 changes: 12 additions & 3 deletions app/models/message.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@ class Message < ApplicationRecord
belongs_to :claim, class_name: 'Claim::BaseClaim'
belongs_to :sender, class_name: 'User', inverse_of: :messages_sent
has_many :user_message_statuses, dependent: :destroy
has_many :documents, -> { where verified: true }, foreign_key: :claim_id, dependent: :destroy, inverse_of: :claim

attr_accessor :claim_action, :written_reasons_submitted

has_one_attached :attachment
has_many_attached :attachments

validates :attachment,
validates :attachments,
size: { less_than: 20.megabytes },
content_type: %w[
application/pdf
Expand All @@ -48,8 +50,9 @@ class Message < ApplicationRecord

scope :most_recent_last, -> { includes(:user_message_statuses).order(created_at: :asc) }

after_create :generate_statuses, :process_claim_action, :process_written_reasons, :send_email_if_required
before_destroy -> { attachment.purge }
after_create :generate_statuses, :process_claim_action, :process_written_reasons, :send_email_if_required,
:duplicate_message_attachment
before_destroy -> { attachments.purge }

class << self
def for(object)
Expand Down Expand Up @@ -107,4 +110,10 @@ def process_written_reasons
def claim_updater
Claims::ExternalUserClaimUpdater.new(claim, current_user: sender)
end

def duplicate_message_attachment
return unless attachment.attached?

attachments.attach(attachment.blob)
end
end
6 changes: 3 additions & 3 deletions app/presenters/message_presenter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ def sender_is_a?(klass)
def body
h.tag.div do
h.concat(simple_format(message.body))
attachment_field if message.attachment.present?
attachment_field if message.attachments.present?
end
end

Expand Down Expand Up @@ -39,11 +39,11 @@ def download_file_link
end

def attachment_file_name
message.attachment.filename.to_s
message.attachments.first.filename.to_s
end

def attachment_file_size
h.number_to_human_size(message.attachment.byte_size)
h.number_to_human_size(message.attachments.first.byte_size)
end

def hide_author?
Expand Down
25 changes: 17 additions & 8 deletions app/views/shared/_message_controls.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,21 @@
link_errors: true,
label: { text: t('.written_reasons') }

= f.govuk_file_field :attachment,
label: { text: t('.attachment_label') },
hint: { text: t('.accepted_files_help_text') }
.moj-multi-file-upload
.moj-multi-file__uploaded-files
%h2.govuk-headings-m Files added
.govuk-summary-list.moj-multi-file-upload__list
.govuk-error-summary{"aria-labelledby" => "error-summary-title", role: "alert", tabindex: "-1", style: "display: none"}
%h2.error-summary-title.govuk-error-summary__title There is a problem
.govuk-list.govuk-error-summary__list
.moj-multi-file__uploaded-fields
.moj-multi-file-upload__upload
.govuk-form-group
%label.govuk-label.govuk-label--m{for: "attachments"}
Upload a file
%input#attachments.govuk-file-upload.moj-multi-file-upload__input{multiple: "multiple", name: "attachments", type: "file"}/

.file-to-be-uploaded.govuk-form-group
%span.filename
= govuk_link_to t('.remove_file_html'), '#'

= f.govuk_submit t('.send'), class: 'govuk-button--secondary'
%button.govuk-button.govuk-button--secondary.moj-multi-file-upload__button{"data-module" => "govuk-button", type: "submit"}
Upload file
%button.govuk-button{"data-module" => "govuk-button", type: "submit"}
Continue
44 changes: 44 additions & 0 deletions app/webpack/javascripts/modules/Modules.MultiFileUpload.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
moj.Modules.MultiFileUpload = {
init: function () {
let container = document.querySelector('.moj-multi-file-upload');
let fields = container.querySelector('.moj-multi-file__uploaded-fields');

new MOJFrontend.MultiFileUpload({
container: container,
uploadUrl: '/documents/upload',
deleteUrl: '/documents/delete',
uploadFileExitHook: function (uploader, file, response) {
console.log('Success fields');
console.log(fields);
let input = document.createElement('input');
input.type = 'hidden';
input.name = 'message[document_ids][]';
input.value = response.file.filename;
fields.appendChild(input);
},
uploadFileErrorHook: function (uploader, file, jqXHR, textStatus, errorThrown) {
console.log('Error fields');
console.log(fields);
let input = document.createElement('input');
input.type = 'hidden';
input.name = 'message[document_ids][]';
input.value = errorThrown;
fields.appendChild(input);

let errorContainer = document.querySelector('.govuk-error-summary');
let errors = errorContainer.querySelector('.govuk-list.govuk-error-summary__list');
errorContainer.style.display = '';
let error = document.createElement('span');
error.style = 'color:#d4351c;font-weight:bold';
error.innerHTML = file.name + ' is ' + errorThrown + '.<br/>';
errors.appendChild(error);
},
fileDeleteHook: function (uploader, response) {
let input = fields.querySelector('input[value="' + response.file.filename + '"]');
console.log('remove input');
console.log(input);
input.parentNode.removeChild(input);
}
});
}
}
1 change: 1 addition & 0 deletions app/webpack/packs/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ import '../javascripts/modules/Helpers.Autocomplete.js'
import '../javascripts/modules/Modules.TableRowClick.js'
import '../javascripts/modules/Modules.AllocationScheme.js'
import '../javascripts/modules/Modules.AddEditAdvocate.js'
import '../javascripts/modules/Modules.MultiFileUpload.js'

import '../javascripts/plugins/jquery.numbered.elements.js'

Expand Down
2 changes: 2 additions & 0 deletions app/webpack/stylesheets/application.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ $govuk-fonts-path: "~govuk-frontend/dist/govuk/assets/fonts/";
@import "~govuk-frontend/dist/govuk/base";
@import "~govuk-frontend/dist/govuk/core/typography";

@import "@ministryofjustice/frontend/moj/components/multi-file-upload/_multi-file-upload.scss";

// Project specific
// Everything below this comment should be project specific.
// If you absolutely need to override gov.uk styles, don't,
Expand Down
1 change: 1 addition & 0 deletions config/initializers/assets.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
Rails.application.config.assets.paths << Rails.root.join('node_modules', 'govuk-frontend', 'dist', 'govuk', 'assets')
Rails.application.config.assets.paths << Rails.root.join('node_modules', 'govuk-frontend', 'dist', 'govuk', 'assets', 'images')
Rails.application.config.assets.paths << Rails.root.join('app', 'webpack', 'packs')
Rails.application.config.assets.paths << Rails.root.join('node_modules', '@ministryofjustice', 'frontend', 'moj', 'assets')
2 changes: 2 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@

resources :documents do
get 'download', on: :member
post 'upload', on: :collection
post 'delete', on: :collection
end

resources :messages, only: [:create] do
Expand Down
3 changes: 2 additions & 1 deletion config/webpack/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ module.exports = {
jQuery: require.resolve('jquery'),
jquery: require.resolve('jquery'),
Dropzone: require.resolve('dropzone/dist/dropzone.js'),
Stickyfill: require.resolve('stickyfilljs')
Stickyfill: require.resolve('stickyfilljs'),
MOJFrontend: require.resolve('@ministryofjustice/frontend/moj/all.js')
})
]
}
26 changes: 26 additions & 0 deletions lib/tasks/documents.rake
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
namespace :documents do
desc 'Copy all message attachment to message attachments.'
task :duplicate_message_attachment => :environment do
messages = Message.all
puts "There are #{messages.count} messages."

messages.each do |message|
if message.attachment.attached?
puts "Duplicating attachment of message ##{message.id}."
attachment_blob = message.attachment.blob

message.attachments.attach(attachment_blob)
puts "Attachment #{attachment_blob.filename} is duplicated in the database."
else
puts "There is no attachment in message ##{message.id}."
end
end
puts "duplicate_message_attachment done!"
end

desc'Count blob map.'
task :count_blob_map => :environment do
blobs = ActiveStorage::Attachment.includes(:blob, blob: :attachments).where(name: 'attachment').map(&:blob)
puts blobs.map { |blob| blob.attachments.count }.tally
end
end
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"@babel/core": "^7.26.0",
"@babel/plugin-transform-runtime": "^7.25.9",
"@babel/preset-env": "^7.26.0",
"@ministryofjustice/frontend": "^2.2.4",
"accessible-autocomplete": "^3.0.1",
"babel-loader": "^9.2.1",
"babel-plugin-macros": "^3.1.0",
Expand Down
4 changes: 2 additions & 2 deletions spec/controllers/messages_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,9 @@
let(:test_url) { 'https://document.storage/attachment.doc#123abc' }

before do
message.attachment.attach(io: StringIO.new, filename: 'attachment.doc')
message.attachments.attach(io: StringIO.new, filename: 'attachment.doc')
allow(Message).to receive(:find).with(message[:id].to_s).and_return(message)
allow(message.attachment.blob).to receive(:url).and_return(test_url)
allow(message.attachments.first.blob).to receive(:url).and_return(test_url)
end

it { is_expected.to redirect_to test_url }
Expand Down
Loading