Merge pull request #3461 from betagouv/improve-uploaded-file-ui
Amélioration de l'UI des fichiers uploadés
This commit is contained in:
commit
0dbe880f51
10 changed files with 130 additions and 34 deletions
|
@ -100,6 +100,11 @@
|
|||
}
|
||||
}
|
||||
|
||||
&.small {
|
||||
line-height: 14px;
|
||||
padding: 5px 10px 6px 10px;
|
||||
}
|
||||
|
||||
&.large {
|
||||
font-size: 18px;
|
||||
line-height: 26px;
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
@import "../constants";
|
||||
|
||||
.piece-justificative-actions {
|
||||
display: flex;
|
||||
margin-bottom: $default-spacer;
|
||||
}
|
||||
|
||||
.piece-justificative-action {
|
||||
margin-right: $default-spacer;
|
||||
|
||||
.button {
|
||||
text-transform: lowercase;
|
||||
}
|
||||
}
|
||||
|
||||
.piece-justificative-input.hidden {
|
||||
display: none;
|
||||
}
|
|
@ -100,9 +100,9 @@
|
|||
input[type=date],
|
||||
input[type=number],
|
||||
input[type=tel],
|
||||
input[type=file],
|
||||
textarea,
|
||||
select {
|
||||
select,
|
||||
.piece-justificative {
|
||||
display: block;
|
||||
margin-bottom: 2 * $default-padding;
|
||||
|
||||
|
@ -111,10 +111,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
.direct-upload {
|
||||
margin-bottom: 2 * $default-padding;
|
||||
}
|
||||
|
||||
.add-row {
|
||||
margin-bottom: 2 * $default-padding;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import '../shared/safari-11-file-xhr-workaround';
|
|||
import '../shared/autocomplete';
|
||||
import '../shared/remote-input';
|
||||
import '../shared/franceconnect';
|
||||
import '../shared/toggle-target';
|
||||
|
||||
import '../new_design/spinner';
|
||||
import '../new_design/dropdown';
|
||||
|
|
20
app/javascript/shared/toggle-target.js
Normal file
20
app/javascript/shared/toggle-target.js
Normal file
|
@ -0,0 +1,20 @@
|
|||
import { delegate, toggle } from '@utils';
|
||||
|
||||
// Unobtrusive Javascript for allowing an element to toggle
|
||||
// the visibility of another element.
|
||||
//
|
||||
// Usage:
|
||||
// <button data-toggle-target="#target">Toggle</button>
|
||||
// <div id="target">Content</div>
|
||||
|
||||
const TOGGLE_SOURCE_SELECTOR = '[data-toggle-target]';
|
||||
|
||||
delegate('click', TOGGLE_SOURCE_SELECTOR, evt => {
|
||||
evt.preventDefault();
|
||||
|
||||
const targetSelector = evt.target.dataset.toggleTarget;
|
||||
const targetElements = document.querySelectorAll(targetSelector);
|
||||
for (let target of targetElements) {
|
||||
toggle(target);
|
||||
}
|
||||
});
|
|
@ -1,2 +1,5 @@
|
|||
<%= render_flash(timeout: 5000, sticky: true) %>
|
||||
<%= remove_element("#piece_justificative_#{@champ.id}") %>
|
||||
|
||||
let fileInputSelector = '<%= "#champs_#{@champ.id}" %>';
|
||||
document.querySelector(fileInputSelector).classList.remove('hidden');
|
||||
|
|
|
@ -78,6 +78,11 @@
|
|||
|
||||
= link_to ".button.without-continuation", "#", class: "button without-continuation"
|
||||
|
||||
%p
|
||||
= link_to ".button.small", "#", class: "button small"
|
||||
|
||||
= link_to ".button.small.primary", "#", class: "button small primary"
|
||||
|
||||
%p
|
||||
= link_to ".button.large", "#", class: "button large"
|
||||
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
- pj = champ.piece_justificative_file
|
||||
- if champ.virus_scan.present?
|
||||
- if champ.virus_scan.safe?
|
||||
= link_to pj.filename.to_s, url_for(pj), target: '_blank'
|
||||
|
||||
.pj-link
|
||||
- if champ.virus_scan.safe? || champ.virus_scan.blank?
|
||||
= link_to url_for(pj), target: '_blank', title: "Télécharger la pièce jointe" do
|
||||
%span.icon.attachment
|
||||
= pj.filename.to_s
|
||||
- if champ.virus_scan.blank?
|
||||
(ce fichier n'a pas été analysé par notre antivirus, téléchargez-le avec précaution)
|
||||
|
||||
- else
|
||||
= pj.filename.to_s
|
||||
- if champ.virus_scan.pending?
|
||||
|
@ -13,6 +19,3 @@
|
|||
(virus détecté, merci d'envoyer un autre fichier)
|
||||
- else
|
||||
(virus détecté, le téléchargement de ce fichier est bloqué)
|
||||
- else
|
||||
= link_to pj.filename.to_s, url_for(pj), target: '_blank'
|
||||
(ce fichier n'a pas été analysé par notre antivirus, téléchargez-le avec précaution)
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
- pj = champ.piece_justificative_file
|
||||
|
||||
- if champ.type_de_champ.piece_justificative_template.attached?
|
||||
%p.edit-pj-template.mb-1
|
||||
Veuillez télécharger, remplir et joindre
|
||||
= link_to('le modèle suivant', url_for(champ.type_de_champ.piece_justificative_template), target: '_blank')
|
||||
.piece-justificative
|
||||
- if champ.type_de_champ.piece_justificative_template.attached?
|
||||
%p.edit-pj-template.mb-1
|
||||
Veuillez télécharger, remplir et joindre
|
||||
= link_to('le modèle suivant', url_for(champ.type_de_champ.piece_justificative_template), target: '_blank')
|
||||
|
||||
- if pj.attached?
|
||||
.piece-justificative-actions{ id: "piece_justificative_#{champ.id}" }
|
||||
.piece-justificative-action
|
||||
= render partial: "shared/champs/piece_justificative/pj_link", locals: { champ: champ, user_can_upload: true }
|
||||
.piece-justificative-action
|
||||
- if champ.private?
|
||||
= link_to 'Supprimer', gestionnaire_champ_purge_champ_piece_justificative_path(procedure_id: champ.dossier.procedure_id, dossier_id: champ.dossier_id, champ_id: champ.id), remote: true, method: :delete, class: 'button small danger'
|
||||
- else
|
||||
= link_to 'Supprimer', champ_purge_champ_piece_justificative_path(id: champ.dossier_id, champ_id: champ.id), remote: true, method: :delete, class: 'button small danger'
|
||||
.piece-justificative-action
|
||||
= button_tag 'Remplacer', type: 'button', class: 'button small', data: { 'toggle-target': "#champs_#{champ.id}" }
|
||||
|
||||
- if !pj.attached?
|
||||
= form.file_field :piece_justificative_file,
|
||||
id: "champs_#{champ.id}",
|
||||
direct_upload: true
|
||||
- else
|
||||
%div{ id: "piece_justificative_#{champ.id}" }
|
||||
= render partial: "shared/champs/piece_justificative/pj_link", locals: { champ: champ, user_can_upload: true }
|
||||
%br
|
||||
- if champ.private?
|
||||
= link_to 'supprimer', gestionnaire_champ_purge_champ_piece_justificative_path(procedure_id: champ.dossier.procedure_id, dossier_id: champ.dossier_id, champ_id: champ.id), remote: true, method: :delete
|
||||
- else
|
||||
= link_to 'supprimer', champ_purge_champ_piece_justificative_path(id: champ.dossier_id, champ_id: champ.id), remote: true, method: :delete
|
||||
%br
|
||||
Modifier :
|
||||
= form.file_field :piece_justificative_file,
|
||||
id: "champs_#{champ.id}",
|
||||
class: "piece-justificative-input #{'hidden' if pj.attached?}",
|
||||
direct_upload: true
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
require 'spec_helper'
|
||||
require 'rails_helper'
|
||||
|
||||
feature 'The user' do
|
||||
let(:password) { 'secret_password' }
|
||||
|
@ -10,7 +10,6 @@ feature 'The user' do
|
|||
# TODO: check
|
||||
# the order
|
||||
# there are no extraneous input
|
||||
# attached file works
|
||||
scenario 'fill a dossier', js: true do
|
||||
allow(Champs::RegionChamp).to receive(:regions).and_return(['region1', 'region2']).at_least(:once)
|
||||
allow(Champs::DepartementChamp).to receive(:departements).and_return(['dep1', 'dep2']).at_least(:once)
|
||||
|
@ -38,10 +37,10 @@ feature 'The user' do
|
|||
select('dep2', from: 'departements')
|
||||
check('engagement')
|
||||
fill_in('dossier_link', with: '123')
|
||||
# do not know how to make it work...
|
||||
# find('form input[type="file"]').set(Rails.root.join('spec/fixtures/files/white.png'))
|
||||
find('.editable-champ-piece_justificative input[type=file]').attach_file(Rails.root + 'spec/fixtures/files/file.pdf')
|
||||
|
||||
click_on 'Enregistrer le brouillon'
|
||||
expect(page).to have_content('Votre brouillon a bien été sauvegardé')
|
||||
|
||||
# check data on the dossier
|
||||
expect(user_dossier.brouillon?).to be true
|
||||
|
@ -62,8 +61,10 @@ feature 'The user' do
|
|||
expect(champ_value_for('departements')).to eq('dep2')
|
||||
expect(champ_value_for('engagement')).to eq('on')
|
||||
expect(champ_value_for('dossier_link')).to eq('123')
|
||||
expect(champ_value_for('piece_justificative')).to be_nil # antivirus hasn't approved the file yet
|
||||
|
||||
## check data on the gui
|
||||
|
||||
expect(page).to have_field('text', with: 'super texte')
|
||||
expect(page).to have_field('textarea', with: 'super textarea')
|
||||
expect(page).to have_field('date', with: '2012-12-12')
|
||||
|
@ -81,6 +82,8 @@ feature 'The user' do
|
|||
expect(page).to have_select('departement', selected: 'dep2')
|
||||
expect(page).to have_checked_field('engagement')
|
||||
expect(page).to have_field('dossier_link', with: '123')
|
||||
expect(page).to have_text('file.pdf')
|
||||
expect(page).to have_text('analyse antivirus en cours')
|
||||
end
|
||||
|
||||
let(:procedure_with_repetition) do
|
||||
|
@ -147,6 +150,48 @@ feature 'The user' do
|
|||
expect(page).to have_current_path(merci_dossier_path(user_dossier))
|
||||
end
|
||||
|
||||
let(:procedure_with_pj) do
|
||||
tdcs = [create(:type_de_champ_piece_justificative, mandatory: true, libelle: 'Pièce justificative')]
|
||||
create(:procedure, :published, :for_individual, types_de_champ: tdcs)
|
||||
end
|
||||
|
||||
scenario 'adding, replacing and removing attachments', js: true do
|
||||
log_in(user.email, password, procedure_with_pj)
|
||||
fill_individual
|
||||
|
||||
# Add an attachment
|
||||
find('.editable-champ-piece_justificative input[type=file]').attach_file(Rails.root + 'spec/fixtures/files/file.pdf')
|
||||
click_on 'Enregistrer le brouillon'
|
||||
expect(page).to have_content('Votre brouillon a bien été sauvegardé')
|
||||
expect(page).to have_text('file.pdf')
|
||||
expect(page).to have_text('analyse antivirus en cours')
|
||||
|
||||
# Mark file as scanned and clean
|
||||
virus_scan = VirusScan.last
|
||||
virus_scan.update(scanned_at: Time.zone.now, status: VirusScan.statuses.fetch(:safe))
|
||||
within '.piece-justificative' do
|
||||
click_on 'rafraichir'
|
||||
end
|
||||
expect(page).to have_link('file.pdf')
|
||||
expect(page).to have_no_content('analyse antivirus en cours')
|
||||
|
||||
# Replace the attachment
|
||||
within '.piece-justificative' do
|
||||
click_on 'Remplacer'
|
||||
end
|
||||
find('.editable-champ-piece_justificative input[type=file]').attach_file(Rails.root + 'spec/fixtures/files/RIB.pdf')
|
||||
click_on 'Enregistrer le brouillon'
|
||||
expect(page).to have_no_text('file.pdf')
|
||||
expect(page).to have_text('RIB.pdf')
|
||||
|
||||
# Remove the attachment
|
||||
within '.piece-justificative' do
|
||||
click_on 'Supprimer'
|
||||
end
|
||||
expect(page).to have_content('La pièce jointe a bien été supprimée')
|
||||
expect(page).to have_no_text('RIB.pdf')
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def log_in(email, password, procedure)
|
||||
|
|
Loading…
Reference in a new issue