diff --git a/app/assets/images/icons/bubble.svg b/app/assets/images/icons/bubble.svg new file mode 100644 index 000000000..d423f2f4b --- /dev/null +++ b/app/assets/images/icons/bubble.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/assets/stylesheets/new_design/dossier_instruction.scss b/app/assets/stylesheets/new_design/dossier_instruction.scss new file mode 100644 index 000000000..6a4ec475c --- /dev/null +++ b/app/assets/stylesheets/new_design/dossier_instruction.scss @@ -0,0 +1,71 @@ +@import "colors"; +@import "common"; +@import "constants"; + +#dossier-instruction { + h1 { + font-size: 18px; + font-weight: bold; + margin-bottom: $default-padding; + } + + .avis-notice { + font-size: 12px; + color: $grey; + margin-bottom: 2 * $default-padding; + } + + input[type=email] { + max-width: 500px; + } + + .avis { + .title { + margin-bottom: $default-padding; + + .count { + display: inline-block; + width: 20px; + height: 20px; + border-radius: 10px; + border: 1px solid $grey; + text-align: center; + font-size: 12px; + font-weight: normal; + margin-left: 8px; + } + } + + .one-avis { + border-top: 1px solid $grey; + padding: $default-padding 0; + + h2 { + font-weight: bold; + margin-bottom: $default-spacer; + + span { + font-weight: normal; + } + } + + .answer { + margin-top: $default-padding; + } + + .avis-icon { + margin-right: $default-spacer; + } + } + + .date, + .waiting { + font-size: 12px; + color: $grey; + } + + .date { + float: right; + } + } +} diff --git a/app/controllers/new_gestionnaire/dossiers_controller.rb b/app/controllers/new_gestionnaire/dossiers_controller.rb index c2e622386..e76364587 100644 --- a/app/controllers/new_gestionnaire/dossiers_controller.rb +++ b/app/controllers/new_gestionnaire/dossiers_controller.rb @@ -12,6 +12,10 @@ module NewGestionnaire @dossier = dossier end + def instruction + @dossier = dossier + end + def follow current_gestionnaire.follow(dossier) dossier.next_step!('gestionnaire', 'follow') @@ -57,6 +61,17 @@ module NewGestionnaire render json: { lon: lon, lat: lat, zoom: zoom, dossier_id: params[:dossier_id] } end + def create_avis + Avis.create(avis_params.merge(claimant: current_gestionnaire, dossier: dossier)) + redirect_to instruction_dossier_path(dossier.procedure, dossier) + end + + def update_annotations + dossier = current_gestionnaire.dossiers.includes(champs_private: :type_de_champ).find(params[:dossier_id]) + dossier.update_attributes(champs_private_params) + redirect_to instruction_dossier_path(dossier.procedure, dossier) + end + private def dossier @@ -66,5 +81,13 @@ module NewGestionnaire def commentaire_params params.require(:commentaire).permit(:body) end + + def avis_params + params.require(:avis).permit(:email, :introduction) + end + + def champs_private_params + params.require(:dossier).permit(champs_private_attributes: [:id, :value, value: []]) + end end end diff --git a/app/models/dossier.rb b/app/models/dossier.rb index fd0a1279a..3c91b9bc7 100644 --- a/app/models/dossier.rb +++ b/app/models/dossier.rb @@ -44,6 +44,7 @@ class Dossier < ActiveRecord::Base belongs_to :user accepts_nested_attributes_for :champs + accepts_nested_attributes_for :champs_private default_scope { where(hidden_at: nil) } scope :state_brouillon, -> { where(state: BROUILLON) } diff --git a/app/views/new_gestionnaire/dossiers/_header.html.haml b/app/views/new_gestionnaire/dossiers/_header.html.haml index 9e503420f..f7aa7eda2 100644 --- a/app/views/new_gestionnaire/dossiers/_header.html.haml +++ b/app/views/new_gestionnaire/dossiers/_header.html.haml @@ -9,7 +9,7 @@ %li = link_to "Demande", dossier_path(dossier.procedure, dossier), class: ("selected" if current_page?(dossier_path(dossier.procedure, dossier))) %li - = link_to "Instruction", "#" + = link_to "Instruction", instruction_dossier_path(dossier.procedure, dossier), class: current_page?(instruction_dossier_path(dossier.procedure, dossier)) ? 'selected' : nil %li = link_to "Messagerie", messagerie_dossier_path(dossier.procedure, dossier), class: current_page?(messagerie_dossier_path(dossier.procedure, dossier)) ? 'selected' : nil %li diff --git a/app/views/new_gestionnaire/dossiers/instruction.html.haml b/app/views/new_gestionnaire/dossiers/instruction.html.haml new file mode 100644 index 000000000..652eda87a --- /dev/null +++ b/app/views/new_gestionnaire/dossiers/instruction.html.haml @@ -0,0 +1,50 @@ += render partial: "header", locals: { dossier: @dossier } + +#dossier-instruction.container + %section + %h1 Inviter une personne à donner son avis + %p.avis-notice Elle pourra consulter, donner un avis sur le dossier et contribuer au fil de messagerie, mais elle ne pourra le modifier. + + = form_for Avis.new, url: avis_dossier_path(@dossier.procedure, @dossier), html: { class: 'form' } do |f| + = f.email_field :email, placeholder: 'Adresse email', required: true + = f.text_area :introduction, rows: 3, value: 'Bonjour, merci de me donner votre avis sur ce dossier.', required: true + .send-wrapper + = f.submit 'Demander un avis', class: 'button send' + + - if @dossier.avis.present? + %section.avis + %h1.title + Avis des invités + %span.count= @dossier.avis.count + + %ul + - @dossier.avis.each do |avis| + %li.one-avis + %h2.claimant + = (avis.claimant.email == current_gestionnaire.email) ? 'Vous' : avis.claimant.email + %span.date Demande d'avis envoyée le #{I18n.l(avis.created_at.localtime, format: '%d/%m/%y')} + %p= avis.introduction + + .answer.flex.align-start + = image_tag 'icons/bubble.svg', class: 'avis-icon' + .width-100 + %h2.gestionnaire + = avis.gestionnaire.email + - if avis.answer.present? + %span.date Réponse donnée le #{I18n.l(avis.updated_at.localtime, format: '%d/%m/%y')} + - else + %span.waiting En attente de réponse + %p= avis.answer + + - if @dossier.ordered_champs_private.present? + %section + %h1.private-annotations Annotations privées + .card.featured + = form_for @dossier, url: annotations_dossier_path(@dossier.procedure, @dossier), html: { class: 'form' } do |f| + = f.fields_for :champs_private, f.object.ordered_champs_private do |champ_form| + - champ = champ_form.object + = render partial: "new_gestionnaire/dossiers/champs/#{champ.type_champ}", + locals: { champ: champ, form: champ_form } + + .send-wrapper + = f.submit 'Sauvegarder', class: 'button send' diff --git a/config/routes.rb b/config/routes.rb index 66c9975d0..6d45eaa11 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -243,14 +243,17 @@ Rails.application.routes.draw do member do get 'attestation' get 'messagerie' + get 'instruction' patch 'follow' patch 'unfollow' patch 'archive' patch 'unarchive' + patch 'annotations' => 'dossiers#update_annotations' post 'commentaire' => 'dossiers#create_commentaire' scope :carte do get 'position' end + post 'avis' => 'dossiers#create_avis' end end end diff --git a/spec/controllers/new_gestionnaire/dossiers_controller_spec.rb b/spec/controllers/new_gestionnaire/dossiers_controller_spec.rb index c1e5ac4c2..032cc83e9 100644 --- a/spec/controllers/new_gestionnaire/dossiers_controller_spec.rb +++ b/spec/controllers/new_gestionnaire/dossiers_controller_spec.rb @@ -94,4 +94,68 @@ describe NewGestionnaire::DossiersController, type: :controller do it { expect(saved_commentaire.dossier).to eq(dossier) } it { expect(response).to redirect_to(messagerie_dossier_path(dossier.procedure, dossier)) } end + + describe "#create_avis" do + let(:saved_avis) { dossier.avis.first } + + before do + post :create_avis, params: { + procedure_id: procedure.id, + dossier_id: dossier.id, + avis: { email: 'email@a.com', introduction: 'intro' } + } + end + + it { expect(saved_avis.email).to eq('email@a.com') } + it { expect(saved_avis.introduction).to eq('intro') } + it { expect(saved_avis.dossier).to eq(dossier) } + it { expect(saved_avis.claimant).to eq(gestionnaire) } + it { expect(response).to redirect_to(instruction_dossier_path(dossier.procedure, dossier)) } + end + + describe "#update_annotations" do + let(:champ_multiple_drop_down_list) do + type_de_champ = TypeDeChamp.create(type_champ: 'multiple_drop_down_list', libelle: 'libelle') + ChampPrivate.create(type_de_champ: type_de_champ) + end + + let(:champ_datetime) do + type_de_champ = TypeDeChamp.create(type_champ: 'datetime', libelle: 'libelle') + ChampPrivate.create(type_de_champ: type_de_champ) + end + + let(:dossier) do + create(:dossier, :replied, procedure: procedure, champs_private: [champ_multiple_drop_down_list, champ_datetime]) + end + + before do + patch :update_annotations, params: { + procedure_id: procedure.id, + dossier_id: dossier.id, + dossier: { + champs_private_attributes: { + '0': { + id: champ_multiple_drop_down_list.id, + value: ['', 'un', 'deux'] + }, + '1': { + id: champ_datetime.id, + 'value(1i)': 2019, + 'value(2i)': 12, + 'value(3i)': 21, + 'value(4i)': 13, + 'value(5i)': 17 + } + } + } + } + + champ_multiple_drop_down_list.reload + champ_datetime.reload + end + + it { expect(champ_multiple_drop_down_list.value).to eq('["un", "deux"]') } + it { expect(champ_datetime.value).to eq('21/12/2019 13:17') } + it { expect(response).to redirect_to(instruction_dossier_path(dossier.procedure, dossier)) } + end end