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 250123 #8115

Open
wants to merge 61 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
db93dfd
Implementation of duplicating message attachment
VinceChiuMOJ Dec 31, 2024
7879485
Fix tests
VinceChiuMOJ Dec 31, 2024
6d1e86d
Update documents.rake
VinceChiuMOJ Dec 31, 2024
f3be39c
Update app/models/message.rb
VinceChiuMOJ Dec 31, 2024
8bb05d3
Update documents.rake
VinceChiuMOJ Dec 31, 2024
ca562dd
refine the original changes on top of CTSKF-1002
VinceChiuMOJ Jan 9, 2025
ae97c64
fix typo
VinceChiuMOJ Jan 9, 2025
6d942e7
Refinement and comment out test for trial
VinceChiuMOJ Jan 9, 2025
0689b29
refine the original changes on top of CTSKF-1002
VinceChiuMOJ Jan 9, 2025
8ff2a95
fix typo
VinceChiuMOJ Jan 9, 2025
5a5f28c
Refinement and comment out test for trial
VinceChiuMOJ Jan 9, 2025
46d2020
Merge branch 'CTSKF-832_250106' of https://github.com/ministryofjusti…
VinceChiuMOJ Jan 16, 2025
f4bab15
Update messaging_steps.rb
VinceChiuMOJ Jan 22, 2025
87a4019
Update with Mark's review
VinceChiuMOJ Jan 28, 2025
11afbfe
bug fix
VinceChiuMOJ Jan 28, 2025
f94f133
remove extra line to pass test
VinceChiuMOJ Jan 28, 2025
63e1b10
Add moj frontend
jrmhaig Dec 9, 2024
061bd31
Add multi file upload from moj frontend
jrmhaig Dec 9, 2024
7d54a5a
Upload files
jrmhaig Dec 9, 2024
e87d7bb
Add hidden fields for documents to message form
jrmhaig Dec 9, 2024
60b39b8
tidied up the ability file
VinceChiuMOJ Dec 12, 2024
23ffa47
Added error handling for multi-file-upload.
VinceChiuMOJ Dec 17, 2024
c7b4e5b
changed font color
VinceChiuMOJ Dec 18, 2024
a606a30
Fixed not showing error returned by the component
VinceChiuMOJ Dec 29, 2024
3767509
Tmp implementation of attaching documents to message
VinceChiuMOJ Dec 29, 2024
a30e9e9
bug fix
VinceChiuMOJ Jan 30, 2025
58bd286
implementation showing multiple attachments
VinceChiuMOJ Jan 30, 2025
f006e35
clear the file list after form submit
VinceChiuMOJ Jan 30, 2025
3296bdd
try to meet Sonarqube standard
VinceChiuMOJ Jan 30, 2025
b08c560
bug fix
VinceChiuMOJ Jan 31, 2025
586924c
fix rspec tests
VinceChiuMOJ Jan 31, 2025
885777b
fix rubocop
VinceChiuMOJ Jan 31, 2025
4264c9b
revert some of the changes in documents_controller.rb
VinceChiuMOJ Feb 3, 2025
bd949c4
refine the original changes on top of CTSKF-1002
VinceChiuMOJ Jan 9, 2025
ac6c70b
fix typo
VinceChiuMOJ Jan 9, 2025
b8fe6e2
Refinement and comment out test for trial
VinceChiuMOJ Jan 9, 2025
ef8d665
Update messaging_steps.rb
VinceChiuMOJ Jan 22, 2025
56e1d85
Update with Mark's review
VinceChiuMOJ Jan 28, 2025
9ef9d4c
bug fix
VinceChiuMOJ Jan 28, 2025
9a80ce1
remove extra line to pass test
VinceChiuMOJ Jan 28, 2025
a5c5f36
Add moj frontend
jrmhaig Dec 9, 2024
f529b67
Add multi file upload from moj frontend
jrmhaig Dec 9, 2024
9e5527e
Upload files
jrmhaig Dec 9, 2024
d6a55d9
Add hidden fields for documents to message form
jrmhaig Dec 9, 2024
2f0abeb
tidied up the ability file
VinceChiuMOJ Dec 12, 2024
1845353
Added error handling for multi-file-upload.
VinceChiuMOJ Dec 17, 2024
2d7c52d
changed font color
VinceChiuMOJ Dec 18, 2024
6858cdf
Fixed not showing error returned by the component
VinceChiuMOJ Dec 29, 2024
f6afa74
Tmp implementation of attaching documents to message
VinceChiuMOJ Dec 29, 2024
ddda841
bug fix
VinceChiuMOJ Jan 30, 2025
65976b8
implementation showing multiple attachments
VinceChiuMOJ Jan 30, 2025
f64baee
clear the file list after form submit
VinceChiuMOJ Jan 30, 2025
cd208eb
try to meet Sonarqube standard
VinceChiuMOJ Jan 30, 2025
d8ccfaa
bug fix
VinceChiuMOJ Jan 31, 2025
266fb79
fix rspec tests
VinceChiuMOJ Jan 31, 2025
64bd7ac
fix rubocop
VinceChiuMOJ Jan 31, 2025
930c151
revert some of the changes in documents_controller.rb
VinceChiuMOJ Feb 3, 2025
d7aef45
Merge branch 'CTSKF-833_bak' into CTSKF-833_250123
VinceChiuMOJ Feb 3, 2025
5bfbaee
Update yarn.lock
VinceChiuMOJ Feb 3, 2025
11a6fa1
Create modules-MultiFileUpload_spec.js
VinceChiuMOJ Feb 5, 2025
211061a
try to pass the test with minimal check
VinceChiuMOJ Feb 5, 2025
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
35 changes: 35 additions & 0 deletions app/controllers/documents_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,24 @@ 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

private

def document
Expand All @@ -56,4 +74,21 @@ def document_params
:creator_id
)
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
end
31 changes: 21 additions & 10 deletions app/controllers/messages_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,19 @@ 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(@message)
save_message(@message)
respond_to do |format|
format.js
format.html { redirect_to redirect_to_url, @notification }
end
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.attachment.blob.url(disposition: 'attachment'), allow_other_host: true
attachment = message.attachments.find(params[:attachment_id])
redirect_to attachment.blob.url(disposition: 'attachment'), allow_other_host: true
end

private
Expand All @@ -59,10 +55,25 @@ def message_params
params.require(:message).permit(
:sender_id,
:claim_id,
:attachment,
:attachments,
:body,
:claim_action,
:written_reasons_submitted
)
end

def attach_documents(message)
documents = Document.where(id: params[:message][:document_ids])
documents.each do |doc|
message.attachments.attach(doc.document.blob)
end
end

def save_message(message)
@notification = if message.save
{ notice: 'Message successfully sent' }
else
{ alert: 'Message not sent: ' + message.errors.full_messages.join(', ') }
end
end
end
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: 4 additions & 11 deletions app/models/message.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ 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 @@ -49,9 +49,8 @@ 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,
:duplicate_message_attachment
before_destroy -> { attachment.purge }
after_create :generate_statuses, :process_claim_action, :process_written_reasons, :send_email_if_required
before_destroy -> { attachments.purge }

class << self
def for(object)
Expand Down Expand Up @@ -109,10 +108,4 @@ 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
25 changes: 14 additions & 11 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 All @@ -24,26 +24,29 @@ def timestamp
private

def attachment_field
h.concat('Attachment: ')
download_file_link
h.concat('Attachments: ')
message.attachments.each do |attachment|
h.concat(h.tag.br)
download_file_link(attachment)
end
end

def download_file_link
def download_file_link(attachment)
h.concat(
h.tag.a(
"#{attachment_file_name} (#{attachment_file_size})",
href: "/messages/#{message.id}/download_attachment",
title: 'Download ' + attachment_file_name
"#{attachment_file_name(attachment)} (#{attachment_file_size(attachment)})",
href: "/messages/#{message.id}/download_attachment?attachment_id=#{attachment.id}",
title: 'Download ' + attachment_file_name(attachment)
)
)
end

def attachment_file_name
message.attachment.filename.to_s
def attachment_file_name(attachment)
attachment.filename.to_s
end

def attachment_file_size
h.number_to_human_size(message.attachment.byte_size)
def attachment_file_size(attachment)
h.number_to_human_size(attachment.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", onclick: "document.querySelector('.govuk-summary-list.moj-multi-file-upload__list').innerHTML = ''"}
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');

let multiFileUpload = 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')
})
]
}
3 changes: 2 additions & 1 deletion features/step_definitions/messaging_steps.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@
When(/^I upload a file$/) do
available_docs = Dir.glob "#{Rails.root}/spec/fixtures/files/*.pdf"
@uploaded_file_path = available_docs.first
@external_user_claim_show_page.messages_panel.upload_file(@uploaded_file_path)
file_field = page.find('input[type="file"]')
file_field.attach_file(@uploaded_file_path)
end

When(/^I click send$/) do
Expand Down
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.7",
"@babel/plugin-transform-runtime": "^7.25.9",
"@babel/preset-env": "^7.26.7",
"@ministryofjustice/frontend": "^2.2.4",
"accessible-autocomplete": "^3.0.1",
"babel-loader": "^9.2.1",
"babel-plugin-macros": "^3.1.0",
Expand Down
Loading