diff --git a/.eslintrc.js b/.eslintrc.js index 6e3ee44b1..8a6120396 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -14,5 +14,13 @@ module.exports = { }, rules: { 'prettier/prettier': 'error' - } + }, + overrides: [ + { + files: ['config/webpack/*.js'], + env: { + node: true + } + } + ] }; diff --git a/app/assets/stylesheets/new_design/dossier_show.scss b/app/assets/stylesheets/new_design/dossier_show.scss index def3e15d3..be12db19e 100644 --- a/app/assets/stylesheets/new_design/dossier_show.scss +++ b/app/assets/stylesheets/new_design/dossier_show.scss @@ -38,4 +38,15 @@ .messagerie-explanation { margin-bottom: $default-padding * 2; } + + .latest-message-section { + display: flex; + flex-direction: column; + max-width: 700px; + margin-bottom: $default-padding * 2; + + .button.send { + align-self: flex-end; + } + } } diff --git a/app/assets/stylesheets/new_design/message.scss b/app/assets/stylesheets/new_design/message.scss index 025a7783e..7c87e763e 100644 --- a/app/assets/stylesheets/new_design/message.scss +++ b/app/assets/stylesheets/new_design/message.scss @@ -9,6 +9,10 @@ background: #FFFFFF; border-radius: 3px; + &.inverted-background { + background: $light-grey; + } + .person-icon { margin-right: $default-spacer; } diff --git a/app/assets/stylesheets/new_design/status_overview.scss b/app/assets/stylesheets/new_design/status_overview.scss index 49ad8a55b..55643b1d3 100644 --- a/app/assets/stylesheets/new_design/status_overview.scss +++ b/app/assets/stylesheets/new_design/status_overview.scss @@ -3,6 +3,7 @@ .status-overview { text-align: center; + margin-bottom: $default-padding * 2; } .status-timeline { diff --git a/app/helpers/commentaire_helper.rb b/app/helpers/commentaire_helper.rb index f22163a07..f42450024 100644 --- a/app/helpers/commentaire_helper.rb +++ b/app/helpers/commentaire_helper.rb @@ -1,10 +1,18 @@ module CommentaireHelper - def commentaire_is_from_me_class(commentaire, email) - if commentaire.email == email + def commentaire_is_from_me_class(commentaire, connected_user) + if commentaire_is_from_me(commentaire, connected_user) "from-me" end end + def commentaire_answer_action(commentaire, connected_user) + if commentaire_is_from_me(commentaire, connected_user) + "Envoyer un message à l’instructeur" + else + "Répondre dans la messagerie" + end + end + def commentaire_is_from_guest(commentaire) commentaire.dossier.invites.map(&:email).include?(commentaire.email) end @@ -14,4 +22,10 @@ module CommentaireHelper template = is_current_year ? :message_date : :message_date_with_year I18n.l(commentaire.created_at.localtime, format: template) end + + private + + def commentaire_is_from_me(commentaire, connected_user) + commentaire.email == connected_user.email + end end diff --git a/app/javascript/packs/application-old.js b/app/javascript/packs/application-old.js index 44fa321c8..214d87b4e 100644 --- a/app/javascript/packs/application-old.js +++ b/app/javascript/packs/application-old.js @@ -1,13 +1,9 @@ +import '../shared/polyfills'; import Turbolinks from 'turbolinks'; import Rails from 'rails-ujs'; import ActiveStorage from '../shared/activestorage/ujs'; import jQuery from 'jquery'; -// Include runtime-polyfills for older browsers. -// Due to .babelrc's 'useBuiltIns', only polyfills actually -// required by the browsers we support will be included. -import 'babel-polyfill'; - import '../shared/sentry'; import '../shared/rails-ujs-fix'; import '../shared/safari-11-file-xhr-workaround'; diff --git a/app/javascript/packs/application.js b/app/javascript/packs/application.js index 971840e3a..196074a15 100644 --- a/app/javascript/packs/application.js +++ b/app/javascript/packs/application.js @@ -1,3 +1,4 @@ +import '../shared/polyfills'; import Turbolinks from 'turbolinks'; import Rails from 'rails-ujs'; import ActiveStorage from '../shared/activestorage/ujs'; @@ -5,11 +6,6 @@ import Chartkick from 'chartkick'; import Highcharts from 'highcharts'; import jQuery from 'jquery'; -// Include runtime-polyfills for older browsers. -// Due to .babelrc's 'useBuiltIns', only polyfills actually -// required by the browsers we support will be included. -import 'babel-polyfill'; - import '../shared/sentry'; import '../shared/rails-ujs-fix'; import '../shared/safari-11-file-xhr-workaround'; diff --git a/app/javascript/shared/polyfills.js b/app/javascript/shared/polyfills.js new file mode 100644 index 000000000..09b38e23e --- /dev/null +++ b/app/javascript/shared/polyfills.js @@ -0,0 +1,5 @@ +// Include runtime-polyfills for older browsers. +// Due to .babelrc's 'useBuiltIns', only polyfills actually +// required by the browsers we support will be included. +import 'babel-polyfill'; +import 'dom4'; diff --git a/app/views/new_user/dossiers/show.html.haml b/app/views/new_user/dossiers/show.html.haml index e6e17707c..b94a0686f 100644 --- a/app/views/new_user/dossiers/show.html.haml +++ b/app/views/new_user/dossiers/show.html.haml @@ -5,3 +5,13 @@ .container = render partial: 'new_user/dossiers/show/status_overview', locals: { dossier: @dossier } + + - latest_message = @dossier.commentaires.last + - if latest_message.present? + .latest-message-section + %h3.tab-title Dernier message + + .message.inverted-background + = render partial: "shared/dossiers/messages/message", locals: { commentaire: latest_message, connected_user: current_user, messagerie_seen_at: nil } + + = link_to commentaire_answer_action(latest_message, current_user), messagerie_dossier_url(@dossier, anchor: 'new_commentaire'), class: 'button send' diff --git a/app/views/shared/dossiers/_messagerie.html.haml b/app/views/shared/dossiers/_messagerie.html.haml index c67d4a174..5d589fa5b 100644 --- a/app/views/shared/dossiers/_messagerie.html.haml +++ b/app/views/shared/dossiers/_messagerie.html.haml @@ -1,7 +1,7 @@ .messagerie.container %ul.messages-list - dossier.commentaires.each do |commentaire| - %li.message{ class: commentaire_is_from_me_class(commentaire, connected_user.email) } + %li.message{ class: commentaire_is_from_me_class(commentaire, connected_user) } = render partial: "shared/dossiers/messages/message", locals: { commentaire: commentaire, connected_user: connected_user, messagerie_seen_at: messagerie_seen_at } = render partial: "shared/dossiers/messages/form", locals: { commentaire: new_commentaire, form_url: form_url } diff --git a/config/webpack/development.js b/config/webpack/development.js index c5edff94a..89d35d938 100644 --- a/config/webpack/development.js +++ b/config/webpack/development.js @@ -1,5 +1,5 @@ -process.env.NODE_ENV = process.env.NODE_ENV || 'development' +process.env.NODE_ENV = process.env.NODE_ENV || 'development'; -const environment = require('./environment') +const environment = require('./environment'); -module.exports = environment.toWebpackConfig() +module.exports = environment.toWebpackConfig(); diff --git a/config/webpack/environment.js b/config/webpack/environment.js index b4f720be3..d261e8336 100644 --- a/config/webpack/environment.js +++ b/config/webpack/environment.js @@ -1,4 +1,4 @@ -const { environment } = require('@rails/webpacker') +const { environment } = require('@rails/webpacker'); // By default don't transpile JS files in ./node_modules – except for some specific modules. const babelLoader = environment.loaders.get('babel'); @@ -6,8 +6,12 @@ babelLoader.exclude = function(modulePath) { let forcedModules = [ 'activestorage' // ActiveStorage uses 'class', which is not supported by IE 11 and older Safari version ]; - return modulePath.includes('node_modules') - && forcedModules.every(forcedModule => !modulePath.includes('node_modules/' + forcedModule)); -} + return ( + modulePath.includes('node_modules') && + forcedModules.every( + forcedModule => !modulePath.includes('node_modules/' + forcedModule) + ) + ); +}; -module.exports = environment +module.exports = environment; diff --git a/config/webpack/production.js b/config/webpack/production.js index 067efd4e4..0103278ee 100644 --- a/config/webpack/production.js +++ b/config/webpack/production.js @@ -1,9 +1,9 @@ -process.env.NODE_ENV = process.env.NODE_ENV || 'production' +process.env.NODE_ENV = process.env.NODE_ENV || 'production'; -const environment = require('./environment') +const environment = require('./environment'); // https://github.com/rails/webpacker/issues/1235 environment.config.optimization.minimizer[0].options.uglifyOptions.ecma = 5; // for IE 11 support environment.config.optimization.minimizer[0].options.uglifyOptions.safari10 = true; -module.exports = environment.toWebpackConfig() +module.exports = environment.toWebpackConfig(); diff --git a/config/webpack/test.js b/config/webpack/test.js index c5edff94a..89d35d938 100644 --- a/config/webpack/test.js +++ b/config/webpack/test.js @@ -1,5 +1,5 @@ -process.env.NODE_ENV = process.env.NODE_ENV || 'development' +process.env.NODE_ENV = process.env.NODE_ENV || 'development'; -const environment = require('./environment') +const environment = require('./environment'); -module.exports = environment.toWebpackConfig() +module.exports = environment.toWebpackConfig(); diff --git a/package.json b/package.json index b68dcd7ed..d40a59cc6 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "autocomplete.js": "^0.31.0", "chartkick": "^2.3.6", "debounce": "^1.2.0", + "dom4": "^2.1.3", "highcharts": "^6.1.1", "jquery": "^3.3.1", "leaflet": "^1.3.1", @@ -21,7 +22,7 @@ "webpack-dev-server": "^3.1.4" }, "scripts": { - "lint:js": "eslint ./app/javascript" + "lint:js": "eslint ./app/javascript ./config/webpack" }, "engines": { "node": "6.* || 8.* || >= 10.*" diff --git a/spec/features/new_user/dossier_details_spec.rb b/spec/features/new_user/dossier_details_spec.rb index d6644e634..41575988b 100644 --- a/spec/features/new_user/dossier_details_spec.rb +++ b/spec/features/new_user/dossier_details_spec.rb @@ -4,7 +4,7 @@ describe 'Dossier details:' do tdcs = [create(:type_de_champ, libelle: 'texte obligatoire')] create(:procedure, :published, :for_individual, types_de_champ: tdcs) end - let(:dossier) { create(:dossier, :en_construction, :for_individual, user: user, procedure: simple_procedure) } + let(:dossier) { create(:dossier, :en_construction, :for_individual, :with_commentaires, user: user, procedure: simple_procedure) } before do Flipflop::FeatureSet.current.test!.switch!(:new_dossier_details, true) @@ -16,6 +16,7 @@ describe 'Dossier details:' do expect(page).to have_current_path(dossier_path(dossier)) expect(page).to have_content(dossier.id) expect(page).to have_selector('.status-explanation') + expect(page).to have_text(dossier.commentaires.last.body) end scenario 'the user can see and edit dossier before instruction' do diff --git a/spec/helpers/commentaire_helper_spec.rb b/spec/helpers/commentaire_helper_spec.rb index 9f0bd998b..36d235f42 100644 --- a/spec/helpers/commentaire_helper_spec.rb +++ b/spec/helpers/commentaire_helper_spec.rb @@ -1,24 +1,36 @@ require 'rails_helper' RSpec.describe CommentaireHelper, type: :helper do - describe ".commentaire_is_from_me_class" do - let(:commentaire) { create(:commentaire, email: "michel@pref.fr") } + let(:commentaire) { create(:commentaire, email: "michel@pref.fr") } + describe ".commentaire_is_from_me_class" do subject { commentaire_is_from_me_class(commentaire, me) } context "when commentaire is from me" do - let(:me) { "michel@pref.fr" } - + let(:me) { User.new(email: "michel@pref.fr") } it { is_expected.to eq("from-me") } end context "when commentaire is not from me" do - let(:me) { "roger@usager.fr" } - + let(:me) { User.new(email: "roger@usager.fr") } it { is_expected.to eq nil } end end + describe '.commentaire_answer_action' do + subject { commentaire_answer_action(commentaire, me) } + + context "when commentaire is from me" do + let(:me) { User.new(email: "michel@pref.fr") } + it { is_expected.to include('Envoyer') } + end + + context "when commentaire is not from me" do + let(:me) { User.new(email: "roger@usager.fr") } + it { is_expected.to include('Répondre') } + end + end + describe '.commentaire_is_from_guest' do let(:dossier) { create(:dossier) } let!(:guest) { create(:invite_user, dossier: dossier) } diff --git a/spec/views/new_user/dossiers/show.html.haml_spec.rb b/spec/views/new_user/dossiers/show.html.haml_spec.rb index 303f1f244..977b5677b 100644 --- a/spec/views/new_user/dossiers/show.html.haml_spec.rb +++ b/spec/views/new_user/dossiers/show.html.haml_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe 'new_user/dossiers/show.html.haml', type: :view do - let(:dossier) { create(:dossier, :en_construction, procedure: create(:procedure)) } + let(:dossier) { create(:dossier, :en_construction) } before do sign_in dossier.user @@ -14,4 +14,15 @@ describe 'new_user/dossiers/show.html.haml', type: :view do expect(rendered).to have_text("Dossier nº #{dossier.id}") expect(rendered).to have_selector('.status-overview') end + + context 'with messages' do + let(:first_message) { create(:commentaire, body: 'Premier message') } + let(:last_message) { create(:commentaire, body: 'Second message') } + let(:dossier) { create(:dossier, :en_construction, commentaires: [first_message, last_message]) } + + it 'displays the last message' do + expect(rendered).not_to have_text(first_message.body) + expect(rendered).to have_text(last_message.body) + end + end end diff --git a/yarn.lock b/yarn.lock index 72a33df3d..2921fab46 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2319,6 +2319,10 @@ doctrine@^2.1.0: dependencies: esutils "^2.0.2" +dom4@^2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/dom4/-/dom4-2.1.3.tgz#f71808fe1f141e4da4ebc43ad5ddb3dd521f2767" + domain-browser@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda"