Merge pull request #3461 from betagouv/improve-uploaded-file-ui

Amélioration de l'UI des fichiers uploadés
This commit is contained in:
Pierre de La Morinerie 2019-02-19 18:07:21 +01:00 committed by GitHub
commit 0dbe880f51
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 130 additions and 34 deletions

View file

@ -100,6 +100,11 @@
}
}
&.small {
line-height: 14px;
padding: 5px 10px 6px 10px;
}
&.large {
font-size: 18px;
line-height: 26px;

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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';

View 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);
}
});

View file

@ -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');

View file

@ -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"

View file

@ -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)

View file

@ -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

View file

@ -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)