Merge pull request #2378 from betagouv/dossier-show

Dossier show
This commit is contained in:
Pierre de La Morinerie 2018-08-13 11:39:35 +02:00 committed by GitHub
commit 65ca41ff8d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 332 additions and 7 deletions

View file

@ -0,0 +1,33 @@
@import "colors";
@import "constants";
#dossier-show {
.sub-header {
.label {
float: right;
margin-left: $default-spacer;
}
.title-container {
margin-bottom: $default-padding * 2;
padding-left: 32px;
.icon.folder {
float: left;
margin-left: -32px;
margin-top: 3px;
}
}
h1 {
color: $black;
font-size: 22px;
margin-bottom: 0;
}
h2 {
color: $grey;
font-weight: bold;
}
}
}

View file

@ -0,0 +1,82 @@
@import "colors";
@import "constants";
.status-progress {
text-align: center;
}
.status-timeline {
display: inline-block;
margin-top: $default-padding * 2;
margin-bottom: $default-padding * 2;
border: 1px solid #808080;
border-radius: 3px;
li {
display: inline-block;
padding-top: $default-spacer;
padding-bottom: $default-spacer;
&:first-child {
padding-left: 20px;
}
&:last-child {
padding-right: 20px;
}
&.active {
font-weight: bold;
}
&.active ~ li {
color: $grey;
}
// Arrows
&:not(:last-child)::after {
content: "";
display: inline-block;
margin-left: 10px;
margin-right: 10px;
vertical-align: top;
}
}
}
.status-explanation {
text-align: left;
&.brouillon,
&.en-construction,
&.en-instruction {
max-width: 600px;
margin: auto;
}
h3 {
font-size: 1.1em;
font-weight: bold;
margin-bottom: $default-spacer;
}
p {
margin-bottom: $default-padding;
}
blockquote {
quotes: "« " " »" "" "";
}
blockquote::before {
content: open-quote;
}
blockquote::after {
content: close-quote;
}
.icon {
margin-right: $default-spacer;
}
}

View file

@ -1,3 +1,4 @@
%h1
Dossier
= @dossier.id
#dossier-show
= render partial: 'new_user/dossiers/show/header', locals: { dossier: @dossier }
= render partial: 'new_user/dossiers/show/resume', locals: { dossier: @dossier }

View file

@ -0,0 +1,12 @@
.sub-header
.container
= render partial: 'shared/dossiers/status', locals: { dossier: dossier }
.title-container
%span.icon.folder
%h1= dossier.procedure.libelle
%h2 Dossier nº #{dossier.id}
%ul.tabs
%li.active
= link_to "Résumé", dossier_path(dossier)

View file

@ -0,0 +1,2 @@
.container
= render partial: 'new_user/dossiers/show/status_progress', locals: { dossier: dossier }

View file

@ -0,0 +1,63 @@
.status-progress
- if !dossier.termine?
%ul.status-timeline
%li.brouillon{ class: dossier.brouillon? ? 'active' : nil }
brouillon
%li.en-construction{ class: dossier.en_construction? ? 'active' : nil }
en construction
%li.en-instruction{ class: dossier.en_instruction? ? 'active' : nil }
en instruction
%li.termine{ class: dossier.termine? ? 'active' : nil }
terminé
.status-explanation
- if dossier.brouillon?
.brouillon
%p Vous pouvez remplir votre dossier tranquillement : il nest pas encore visible par ladministration.
%p Quand vous aurez terminé, soumettez votre dossier pour quil soit examiné.
- elsif dossier.en_construction?
.en-construction
%p Un accompagnant de ladministration est en train de vérifier que votre dossier est bien complet.
%p Si des modifications sont nécessaires, vous recevrez un email avec les modifications à effectuer. Et sinon, dès que votre dossier sera complet, il passera automatiquement en instruction.
- elsif dossier.en_instruction?
.en-instruction
%p Votre dossier est complet. Il est en cours dexamen par les agent·e·s de ladministration.
%p Dès que ladministration aura statué sur votre dossier, vous recevrez un email avec le résultat.
- elsif dossier.accepte?
.accepte
%p
%span.icon.accept
Votre dossier a été
= succeed '.' do
%strong accepté
- if dossier.motivation.present?
%h3 Motif de lacceptation
%blockquote= dossier.motivation
- elsif dossier.refuse?
.refuse
%p
%span.icon.refuse
Nous sommes désolés, votre dossier a malheureusement été
= succeed '.' do
%strong refusé
- if dossier.motivation.present?
%h3 Motif du refus
%blockquote= dossier.motivation
- elsif dossier.sans_suite?
.sans-suite
%p
%span.icon.without-continuation
Votre dossier a été classé
= succeed '.' do
%strong sans suite
- if dossier.motivation.present?
%h3 Motif du classement sans suite
%blockquote= dossier.motivation

View file

@ -1,9 +1,9 @@
- if dossier.brouillon?
%span.label.brouillon brouillon
- if dossier.en_instruction?
%span.label.instruction en instruction
- elsif dossier.en_construction?
%span.label.construction en construction
- if dossier.en_instruction?
%span.label.instruction en instruction
- elsif dossier.accepte?
%span.label.accepted accepté
- elsif dossier.refuse?

View file

@ -87,5 +87,48 @@ FactoryBot.define do
dossier.save!
end
end
trait :accepte do
after(:create) do |dossier, _evaluator|
dossier.state = 'accepte'
dossier.processed_at = dossier.created_at + 1.minute
dossier.en_construction_at = dossier.created_at + 2.minutes
dossier.created_at = dossier.created_at + 3.minutes
dossier.save!
end
end
trait :refuse do
after(:create) do |dossier, _evaluator|
dossier.state = 'refuse'
dossier.processed_at = dossier.created_at + 1.minute
dossier.en_construction_at = dossier.created_at + 2.minutes
dossier.created_at = dossier.created_at + 3.minutes
dossier.save!
end
end
trait :sans_suite do
after(:create) do |dossier, _evaluator|
dossier.state = 'sans_suite'
dossier.processed_at = dossier.created_at + 1.minute
dossier.en_construction_at = dossier.created_at + 2.minutes
dossier.created_at = dossier.created_at + 3.minutes
dossier.save!
end
end
trait :with_motivation do
after(:create) do |dossier, _evaluator|
dossier.motivation = case dossier.state
when 'refuse'
'Lentreprise concernée nest pas agréée.'
when 'sans_suite'
'Le département nest pas éligible. Veuillez remplir un nouveau dossier auprès de la DDT du 93.'
else
'Vous avez validé les conditions.'
end
end
end
end
end

View file

@ -6,11 +6,12 @@ describe 'Dossier details:' do
Flipflop::FeatureSet.current.test!.switch!(:new_dossier_details, true)
end
scenario 'the user can see the details of their dossier' do
scenario 'the user can see the summary of the dossier status' do
visit_dossier dossier
expect(page).to have_current_path(dossier_path(dossier))
expect(page).to have_content(dossier.id)
expect(page).to have_selector('.status-explanation')
end
private

View file

@ -11,6 +11,7 @@ describe 'new_user/dossiers/show.html.haml', type: :view do
subject! { render }
it 'affiche les informations du dossier' do
expect(rendered).to have_text("Dossier #{dossier.id}")
expect(rendered).to have_text(dossier.procedure.libelle)
expect(rendered).to have_text("Dossier nº #{dossier.id}")
end
end

View file

@ -0,0 +1,87 @@
describe 'new_user/dossiers/show/_status_progress.html.haml', type: :view do
subject! { render 'new_user/dossiers/show/status_progress.html.haml', dossier: dossier }
matcher :have_timeline_item do |selector|
match do |rendered|
expect(rendered).to have_selector(item_selector(selector))
end
chain :active do
@active = true
end
chain :inactive do
@active = false
end
def item_selector(selector)
item_selector = ".status-timeline #{selector}"
item_selector += '.active' if @active == true
item_selector += ':not(.active)' if @active == false
item_selector
end
end
context 'when brouillon' do
let(:dossier) { create :dossier }
it 'renders the timeline (without the final states)' do
expect(rendered).to have_timeline_item('.brouillon').active
expect(rendered).to have_timeline_item('.en-construction').inactive
expect(rendered).to have_timeline_item('.en-instruction').inactive
expect(rendered).to have_timeline_item('.termine').inactive
end
it { is_expected.to have_selector('.status-explanation .brouillon') }
end
context 'when en construction' do
let(:dossier) { create :dossier, :en_construction }
it 'renders the timeline (without the final states)' do
expect(rendered).to have_timeline_item('.brouillon').inactive
expect(rendered).to have_timeline_item('.en-construction').active
expect(rendered).to have_timeline_item('.en-instruction').inactive
expect(rendered).to have_timeline_item('.termine').inactive
end
it { is_expected.to have_selector('.status-explanation .en-construction') }
end
context 'when en instruction' do
let(:dossier) { create :dossier, :en_instruction }
it 'renders the timeline (without the final states)' do
expect(rendered).to have_timeline_item('.brouillon').inactive
expect(rendered).to have_timeline_item('.en-construction').inactive
expect(rendered).to have_timeline_item('.en-instruction').active
expect(rendered).to have_timeline_item('.termine').inactive
end
it { is_expected.to have_selector('.status-explanation .en-instruction') }
end
context 'when accepté' do
let(:dossier) { create :dossier, :accepte, :with_motivation }
it { is_expected.not_to have_selector('.status-timeline') }
it { is_expected.to have_selector('.status-explanation .accepte') }
it { is_expected.to have_text(dossier.motivation) }
end
context 'when refusé' do
let(:dossier) { create :dossier, :refuse, :with_motivation }
it { is_expected.not_to have_selector('.status-timeline') }
it { is_expected.to have_selector('.status-explanation .refuse') }
it { is_expected.to have_text(dossier.motivation) }
end
context 'when classé sans suite' do
let(:dossier) { create :dossier, :sans_suite, :with_motivation }
it { is_expected.not_to have_selector('.status-timeline') }
it { is_expected.to have_selector('.status-explanation .sans-suite') }
it { is_expected.to have_text(dossier.motivation) }
end
end