From ed118523001e128d070c0be87a13bbb3554a5c3e Mon Sep 17 00:00:00 2001 From: gregoirenovel Date: Wed, 10 Oct 2018 09:06:32 +0200 Subject: [PATCH 01/10] Delete the InviteGestionnaire model --- app/models/dossier.rb | 1 - app/models/invite_gestionnaire.rb | 2 -- app/serializers/dossier_serializer.rb | 7 +------ db/migrate/20181010070424_remove_type_from_invites.rb | 5 +++++ db/schema.rb | 3 +-- spec/controllers/api/v1/dossiers_controller_spec.rb | 2 +- 6 files changed, 8 insertions(+), 12 deletions(-) delete mode 100644 app/models/invite_gestionnaire.rb create mode 100644 db/migrate/20181010070424_remove_type_from_invites.rb diff --git a/app/models/dossier.rb b/app/models/dossier.rb index 49078dd1e..531b511ea 100644 --- a/app/models/dossier.rb +++ b/app/models/dossier.rb @@ -25,7 +25,6 @@ class Dossier < ApplicationRecord has_many :commentaires, dependent: :destroy has_many :invites, dependent: :destroy has_many :invites_user, class_name: 'InviteUser', dependent: :destroy - has_many :invites_gestionnaires, class_name: 'InviteGestionnaire', dependent: :destroy has_many :follows has_many :followers_gestionnaires, through: :follows, source: :gestionnaire has_many :avis, dependent: :destroy diff --git a/app/models/invite_gestionnaire.rb b/app/models/invite_gestionnaire.rb deleted file mode 100644 index fabc49f36..000000000 --- a/app/models/invite_gestionnaire.rb +++ /dev/null @@ -1,2 +0,0 @@ -class InviteGestionnaire < Invite -end diff --git a/app/serializers/dossier_serializer.rb b/app/serializers/dossier_serializer.rb index 252c362e6..a35e5ba57 100644 --- a/app/serializers/dossier_serializer.rb +++ b/app/serializers/dossier_serializer.rb @@ -10,8 +10,7 @@ class DossierSerializer < ActiveModel::Serializer :received_at, :processed_at, :motivation, - :instructeurs, - :invites + :instructeurs has_one :individual has_one :entreprise @@ -62,10 +61,6 @@ class DossierSerializer < ActiveModel::Serializer object.followers_gestionnaires.pluck(:email) end - def invites - object.invites_gestionnaires.pluck(:email) - end - private def user_geometry(dossier) diff --git a/db/migrate/20181010070424_remove_type_from_invites.rb b/db/migrate/20181010070424_remove_type_from_invites.rb new file mode 100644 index 000000000..69fab420f --- /dev/null +++ b/db/migrate/20181010070424_remove_type_from_invites.rb @@ -0,0 +1,5 @@ +class RemoveTypeFromInvites < ActiveRecord::Migration[5.2] + def change + remove_column :invites, :type + end +end diff --git a/db/schema.rb b/db/schema.rb index b93d621b6..bc277e782 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2018_10_02_164310) do +ActiveRecord::Schema.define(version: 2018_10_10_070424) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -384,7 +384,6 @@ ActiveRecord::Schema.define(version: 2018_10_02_164310) do t.string "email_sender" t.integer "dossier_id" t.integer "user_id" - t.string "type", default: "InviteGestionnaire" t.datetime "created_at" t.datetime "updated_at" end diff --git a/spec/controllers/api/v1/dossiers_controller_spec.rb b/spec/controllers/api/v1/dossiers_controller_spec.rb index de3ef4f3e..ff66fb2f0 100644 --- a/spec/controllers/api/v1/dossiers_controller_spec.rb +++ b/spec/controllers/api/v1/dossiers_controller_spec.rb @@ -139,7 +139,7 @@ describe API::V1::DossiersController do let!(:dossier) { Timecop.freeze(date_creation) { create(:dossier, :with_entreprise, procedure: procedure, motivation: "Motivation") } } let(:dossier_id) { dossier.id } let(:body) { JSON.parse(retour.body, symbolize_names: true) } - let(:field_list) { [:id, :created_at, :updated_at, :archived, :individual, :entreprise, :etablissement, :cerfa, :types_de_piece_justificative, :pieces_justificatives, :champs, :champs_private, :commentaires, :state, :simplified_state, :initiated_at, :processed_at, :received_at, :motivation, :email, :instructeurs, :invites] } + let(:field_list) { [:id, :created_at, :updated_at, :archived, :individual, :entreprise, :etablissement, :cerfa, :types_de_piece_justificative, :pieces_justificatives, :champs, :champs_private, :commentaires, :state, :simplified_state, :initiated_at, :processed_at, :received_at, :motivation, :email, :instructeurs] } subject { body[:dossier] } it 'return REST code 200', :show_in_doc do From c8f872c56634b68940b2b08a44dd4601bfc3110f Mon Sep 17 00:00:00 2001 From: gregoirenovel Date: Wed, 10 Oct 2018 09:23:08 +0200 Subject: [PATCH 02/10] =?UTF-8?q?InviteUser=20=E2=86=92=20Invite?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/invites_controller.rb | 2 +- app/models/commentaire.rb | 2 +- app/models/dossier.rb | 3 +-- app/models/invite_user.rb | 2 -- spec/controllers/invites_controller_spec.rb | 6 ++--- .../new_user/dossiers_controller_spec.rb | 24 +++++++++---------- .../users/carte_controller_spec.rb | 2 +- spec/controllers/users_controller_spec.rb | 2 +- spec/factories/invite_user.rb | 24 ------------------- spec/features/new_user/invite_spec.rb | 4 ++-- spec/helpers/commentaire_helper_spec.rb | 2 +- spec/models/user_spec.rb | 4 ++-- 12 files changed, 25 insertions(+), 52 deletions(-) delete mode 100644 app/models/invite_user.rb delete mode 100644 spec/factories/invite_user.rb diff --git a/app/controllers/invites_controller.rb b/app/controllers/invites_controller.rb index d3cd732de..10a5f0139 100644 --- a/app/controllers/invites_controller.rb +++ b/app/controllers/invites_controller.rb @@ -5,7 +5,7 @@ class InvitesController < ApplicationController email = params[:invite_email].downcase dossier = current_user.dossiers.find(params[:dossier_id]) - invite = InviteUser.create( + invite = Invite.create( dossier: dossier, user: User.find_by(email: email), email: email, diff --git a/app/models/commentaire.rb b/app/models/commentaire.rb index 1096081d2..e3b3d2c72 100644 --- a/app/models/commentaire.rb +++ b/app/models/commentaire.rb @@ -35,7 +35,7 @@ class Commentaire < ApplicationRecord def notify dossier_user_email = dossier.user.email - invited_users_emails = dossier.invites_user.pluck(:email).to_a + invited_users_emails = dossier.invites.pluck(:email).to_a # - If the email is the contact email, the commentaire is a copy # of an automated notification email we sent to a user, so do nothing. diff --git a/app/models/dossier.rb b/app/models/dossier.rb index 531b511ea..a13f01e50 100644 --- a/app/models/dossier.rb +++ b/app/models/dossier.rb @@ -24,7 +24,6 @@ class Dossier < ApplicationRecord has_many :cadastres, dependent: :destroy has_many :commentaires, dependent: :destroy has_many :invites, dependent: :destroy - has_many :invites_user, class_name: 'InviteUser', dependent: :destroy has_many :follows has_many :followers_gestionnaires, through: :follows, source: :gestionnaire has_many :avis, dependent: :destroy @@ -159,7 +158,7 @@ class Dossier < ApplicationRecord end def invite_for_user(user) - invites_user.find_by(user_id: user.id) + invites.find_by(user_id: user.id) end def can_be_en_construction? diff --git a/app/models/invite_user.rb b/app/models/invite_user.rb deleted file mode 100644 index c599c2f23..000000000 --- a/app/models/invite_user.rb +++ /dev/null @@ -1,2 +0,0 @@ -class InviteUser < Invite -end diff --git a/spec/controllers/invites_controller_spec.rb b/spec/controllers/invites_controller_spec.rb index 31035d801..741743231 100644 --- a/spec/controllers/invites_controller_spec.rb +++ b/spec/controllers/invites_controller_spec.rb @@ -44,7 +44,7 @@ describe InvitesController, type: :controller do sign_in(user) end - it { expect { subject }.to change(InviteUser, :count).by(1) } + it { expect { subject }.to change(Invite, :count).by(1) } end end end @@ -54,7 +54,7 @@ describe InvitesController, type: :controller do shared_examples_for "he can not create a invite" do it { expect { subject }.to raise_error(ActiveRecord::RecordNotFound) } - it { expect { subject rescue nil }.to change(InviteUser, :count).by(0) } + it { expect { subject rescue nil }.to change(Invite, :count).by(0) } end context 'when user has no access to dossier' do @@ -73,7 +73,7 @@ describe InvitesController, type: :controller do dossier.update(user: signed_in_profile) end - it { expect { subject }.to change(InviteUser, :count).by(1) } + it { expect { subject }.to change(Invite, :count).by(1) } it "redirects to the previous URL" do expect(subject).to redirect_to("/dossiers/#{dossier.id}/brouillon") diff --git a/spec/controllers/new_user/dossiers_controller_spec.rb b/spec/controllers/new_user/dossiers_controller_spec.rb index 799c6c40b..4aa0292bf 100644 --- a/spec/controllers/new_user/dossiers_controller_spec.rb +++ b/spec/controllers/new_user/dossiers_controller_spec.rb @@ -50,13 +50,13 @@ describe NewUser::DossiersController, type: :controller do end context 'when an invite asks for a dossier where they were invited' do - before { create(:invite, dossier: asked_dossier, user: user, type: 'InviteUser') } + before { create(:invite, dossier: asked_dossier, user: user) } it_behaves_like 'redirects and flashes' end context 'when an invite asks for another dossier' do - before { create(:invite, dossier: create(:dossier), user: user, type: 'InviteUser') } + before { create(:invite, dossier: create(:dossier), user: user) } it_behaves_like 'redirects and flashes' end @@ -84,13 +84,13 @@ describe NewUser::DossiersController, type: :controller do end context 'when an invite asks for a dossier where they were invited' do - before { create(:invite, dossier: asked_dossier, user: user, type: 'InviteUser') } + before { create(:invite, dossier: asked_dossier, user: user) } it_behaves_like 'does not redirect nor flash' end context 'when an invite asks for another dossier' do - before { create(:invite, dossier: create(:dossier), user: user, type: 'InviteUser') } + before { create(:invite, dossier: create(:dossier), user: user) } it_behaves_like 'redirects and flashes' end @@ -123,14 +123,14 @@ describe NewUser::DossiersController, type: :controller do end context 'when an invite save the draft for a dossier where they where invited' do - before { create(:invite, dossier: asked_dossier, user: user, type: 'InviteUser') } + before { create(:invite, dossier: asked_dossier, user: user) } let(:draft) { true } it_behaves_like 'does not redirect nor flash' end context 'when an invite submit a dossier where they where invited' do - before { create(:invite, dossier: asked_dossier, user: user, type: 'InviteUser') } + before { create(:invite, dossier: asked_dossier, user: user) } let(:draft) { false } it_behaves_like 'redirects and flashes' @@ -370,7 +370,7 @@ describe NewUser::DossiersController, type: :controller do context 'when the user has an invitation but is not the owner' do let(:dossier) { create(:dossier) } - let!(:invite) { create(:invite, dossier: dossier, user: user, type: 'InviteUser') } + let!(:invite) { create(:invite, dossier: dossier, user: user) } context 'and the invite saves a draft' do let(:payload) { submit_payload.merge(save_draft: true) } @@ -493,7 +493,7 @@ describe NewUser::DossiersController, type: :controller do context 'when the user has an invitation but is not the owner' do let(:dossier) { create(:dossier) } - let!(:invite) { create(:invite, dossier: dossier, user: user, type: 'InviteUser') } + let!(:invite) { create(:invite, dossier: dossier, user: user) } before do dossier.en_construction! @@ -525,7 +525,7 @@ describe NewUser::DossiersController, type: :controller do end context 'when the user only have some dossiers invites' do - let!(:invite) { create(:invite, dossier: create(:dossier), user: user, type: 'InviteUser') } + let!(:invite) { create(:invite, dossier: create(:dossier), user: user) } before { get(:index) } @@ -535,7 +535,7 @@ describe NewUser::DossiersController, type: :controller do context 'when the user has both' do let!(:own_dossier) { create(:dossier, user: user) } - let!(:invite) { create(:invite, dossier: create(:dossier), user: user, type: 'InviteUser') } + let!(:invite) { create(:invite, dossier: create(:dossier), user: user) } context 'and there is no current_tab param' do before { get(:index) } @@ -560,8 +560,8 @@ describe NewUser::DossiersController, type: :controller do before do Timecop.freeze(4.days.ago) { create(:dossier, user: user) } Timecop.freeze(2.days.ago) { create(:dossier, user: user) } - Timecop.freeze(4.days.ago) { create(:invite, dossier: create(:dossier), user: user, type: 'InviteUser') } - Timecop.freeze(2.days.ago) { create(:invite, dossier: create(:dossier), user: user, type: 'InviteUser') } + Timecop.freeze(4.days.ago) { create(:invite, dossier: create(:dossier), user: user) } + Timecop.freeze(2.days.ago) { create(:invite, dossier: create(:dossier), user: user) } get(:index) end diff --git a/spec/controllers/users/carte_controller_spec.rb b/spec/controllers/users/carte_controller_spec.rb index 8cea48644..5b238161c 100644 --- a/spec/controllers/users/carte_controller_spec.rb +++ b/spec/controllers/users/carte_controller_spec.rb @@ -17,7 +17,7 @@ RSpec.describe Users::CarteController, type: :controller do let(:adresse) { etablissement.geo_adresse } before do - create :invite, dossier: dossier, user: invite_by_user, email: invite_by_user.email, type: 'InviteUser' + create :invite, dossier: dossier, user: invite_by_user, email: invite_by_user.email sign_in user end diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb index a5a7b8558..0af27ab75 100644 --- a/spec/controllers/users_controller_spec.rb +++ b/spec/controllers/users_controller_spec.rb @@ -20,7 +20,7 @@ describe UsersController, type: :controller do context 'when user is invite by the owner' do before do - create :invite, email: invite_user.email, dossier: dossier, user: invite_user, type: 'InviteUser' + create :invite, email: invite_user.email, dossier: dossier, user: invite_user sign_in invite_user end diff --git a/spec/factories/invite_user.rb b/spec/factories/invite_user.rb deleted file mode 100644 index eb9363240..000000000 --- a/spec/factories/invite_user.rb +++ /dev/null @@ -1,24 +0,0 @@ -FactoryBot.define do - factory :invite_user do - email { 'plop@octo.com' } - - after(:build) do |invite, _evaluator| - if invite.dossier.nil? - invite.dossier = create(:dossier) - end - - if invite.user.present? - invite.email = invite.user.email - end - end - - trait :with_user do - after(:build) do |invite, _evaluator| - if invite.user.nil? - invite.user = create(:user) - invite.email = invite.user.email - end - end - end - end -end diff --git a/spec/features/new_user/invite_spec.rb b/spec/features/new_user/invite_spec.rb index 60b5cc0f7..31e876e1e 100644 --- a/spec/features/new_user/invite_spec.rb +++ b/spec/features/new_user/invite_spec.rb @@ -5,7 +5,7 @@ feature 'Invitations' do let(:owner) { create(:user) } let(:invited_user) { create(:user, email: 'user_invite@exemple.fr') } let(:procedure) { create(:simple_procedure) } - let(:invite) { create(:invite_user, user: invited_user, dossier: dossier) } + let(:invite) { create(:invite, user: invited_user, dossier: dossier) } context 'when the dossier is a brouillon' do let!(:dossier) { create(:dossier, :for_individual, state: Dossier.states.fetch(:brouillon), user: owner, procedure: procedure) } @@ -26,7 +26,7 @@ feature 'Invitations' do end context 'when inviting someone without an existing account' do - let(:invite) { create(:invite_user, dossier: dossier, user: nil) } + let(:invite) { create(:invite, dossier: dossier, user: nil) } let(:user_password) { 'l33tus3r' } scenario 'an invited user can register using the registration link sent in the invitation email' do diff --git a/spec/helpers/commentaire_helper_spec.rb b/spec/helpers/commentaire_helper_spec.rb index 36d235f42..cd1a05608 100644 --- a/spec/helpers/commentaire_helper_spec.rb +++ b/spec/helpers/commentaire_helper_spec.rb @@ -33,7 +33,7 @@ RSpec.describe CommentaireHelper, type: :helper do describe '.commentaire_is_from_guest' do let(:dossier) { create(:dossier) } - let!(:guest) { create(:invite_user, dossier: dossier) } + let!(:guest) { create(:invite, dossier: dossier) } subject { commentaire_is_from_guest(commentaire) } diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index d4217f023..942283c16 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -66,7 +66,7 @@ describe User, type: :model do context 'when user was invited by user' do before do - create(:invite, dossier: dossier, user: invite_user, type: 'InviteUser') + create(:invite, dossier: dossier, user: invite_user) end let(:user) { invite_user } @@ -116,7 +116,7 @@ describe User, type: :model do context 'when user was invited by user' do before do - create(:invite, dossier: dossier, user: invite_user, type: 'InviteUser') + create(:invite, dossier: dossier, user: invite_user) end let(:user) { invite_user } From c343893d004fd8596b6c31b7437b97f59e14a3e6 Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Tue, 9 Oct 2018 11:32:27 +0200 Subject: [PATCH 03/10] Expose all utils function as @utils --- app/javascript/shared/utils.js | 44 ++++++++++++++++++++++++++++++++++ config/webpack/environment.js | 9 +++++++ 2 files changed, 53 insertions(+) diff --git a/app/javascript/shared/utils.js b/app/javascript/shared/utils.js index 9339dd07f..8270f4d70 100644 --- a/app/javascript/shared/utils.js +++ b/app/javascript/shared/utils.js @@ -1,3 +1,10 @@ +import Rails from 'rails-ujs'; +import $ from 'jquery'; +import debounce from 'debounce'; + +export { debounce }; +export const { fire } = Rails; + export function show({ classList }) { classList.remove('hidden'); } @@ -9,3 +16,40 @@ export function hide({ classList }) { export function toggle({ classList }) { classList.toggle('hidden'); } + +export function delegate(eventNames, selector, callback) { + eventNames + .split(' ') + .forEach(eventName => + Rails.delegate(document, selector, eventName, callback) + ); +} + +export function getJSON(url, data, method = 'get') { + data = method !== 'get' ? JSON.stringify(data) : data; + return $.ajax({ + method, + url, + data, + contentType: 'application/json', + dataType: 'json' + }); +} + +export function scrollTo(container, scrollTo) { + $(container).scrollTop( + $(scrollTo).offset().top - + $(container).offset().top + + $(container).scrollTop() + ); +} + +export function scrollToBottom(container) { + $(container).scrollTop(container.scrollHeight); +} + +export function on(selector, eventName, fn) { + [...document.querySelectorAll(selector)].forEach(element => + element.addEventListener(eventName, event => fn(event, event.detail)) + ); +} diff --git a/config/webpack/environment.js b/config/webpack/environment.js index d261e8336..6016319bc 100644 --- a/config/webpack/environment.js +++ b/config/webpack/environment.js @@ -1,3 +1,4 @@ +const path = require('path'); const { environment } = require('@rails/webpacker'); // By default don't transpile JS files in ./node_modules – except for some specific modules. @@ -14,4 +15,12 @@ babelLoader.exclude = function(modulePath) { ); }; +const resolve = { + alias: { + '@utils': path.resolve(__dirname, '..', '..', 'app/javascript/shared/utils') + } +}; + +environment.config.merge({ resolve }); + module.exports = environment; From 8c16eb4cd0b895c47cbe733ff5d3e3725063a1f1 Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Tue, 9 Oct 2018 11:35:22 +0200 Subject: [PATCH 04/10] Use @utils instead of jQuery --- app/javascript/new_design/carto.js | 6 +++--- app/javascript/new_design/dropdown.js | 8 +++----- app/javascript/new_design/spinner.js | 11 ++++------- app/javascript/shared/autocomplete.js | 6 +++--- app/javascript/shared/rails-ujs-fix.js | 3 ++- app/javascript/shared/remote-input.js | 7 ++----- 6 files changed, 17 insertions(+), 24 deletions(-) diff --git a/app/javascript/new_design/carto.js b/app/javascript/new_design/carto.js index 11fbbe75d..895a613ba 100644 --- a/app/javascript/new_design/carto.js +++ b/app/javascript/new_design/carto.js @@ -1,5 +1,5 @@ -import $ from 'jquery'; import L from 'leaflet'; +import { getJSON } from '@utils'; import { getData } from '../shared/data'; import { DEFAULT_POSITION } from '../shared/carto'; @@ -11,8 +11,8 @@ import { } from './carto/draw'; function initialize() { - if ($('#map').length > 0) { - $.getJSON(getData('carto').getPositionUrl).then( + if (document.getElementById('map')) { + getJSON(getData('carto').getPositionUrl).then( position => initializeWithPosition(position), () => initializeWithPosition(DEFAULT_POSITION) ); diff --git a/app/javascript/new_design/dropdown.js b/app/javascript/new_design/dropdown.js index 2829b98d8..13d8965c2 100644 --- a/app/javascript/new_design/dropdown.js +++ b/app/javascript/new_design/dropdown.js @@ -1,8 +1,6 @@ -import Rails from 'rails-ujs'; +import { delegate } from '@utils'; -const { delegate } = Rails; - -delegate(document, 'body', 'click', event => { +delegate('click', 'body', event => { if (!event.target.closest('.dropdown')) { [...document.querySelectorAll('.dropdown')].forEach(element => element.classList.remove('open', 'fade-in-down') @@ -10,7 +8,7 @@ delegate(document, 'body', 'click', event => { } }); -delegate(document, '.dropdown-button', 'click', event => { +delegate('click', '.dropdown-button', event => { event.stopPropagation(); const parent = event.target.closest('.dropdown-button').parentElement; if (parent.classList.contains('dropdown')) { diff --git a/app/javascript/new_design/spinner.js b/app/javascript/new_design/spinner.js index 7c92ca53b..8b1fbac3e 100644 --- a/app/javascript/new_design/spinner.js +++ b/app/javascript/new_design/spinner.js @@ -1,7 +1,4 @@ -import Rails from 'rails-ujs'; -import { show, hide } from '../shared/utils'; - -const { delegate } = Rails; +import { show, hide, delegate } from '@utils'; function showSpinner() { [...document.querySelectorAll('.spinner')].forEach(show); @@ -11,6 +8,6 @@ function hideSpinner() { [...document.querySelectorAll('.spinner')].forEach(hide); } -delegate(document, '[data-spinner]', 'ajax:complete', hideSpinner); -delegate(document, '[data-spinner]', 'ajax:stopped', hideSpinner); -delegate(document, '[data-spinner]', 'ajax:send', showSpinner); +delegate('ajax:complete', '[data-spinner]', hideSpinner); +delegate('ajax:stopped', '[data-spinner]', hideSpinner); +delegate('ajax:send', '[data-spinner]', showSpinner); diff --git a/app/javascript/shared/autocomplete.js b/app/javascript/shared/autocomplete.js index 727ae172a..809373bf1 100644 --- a/app/javascript/shared/autocomplete.js +++ b/app/javascript/shared/autocomplete.js @@ -1,5 +1,5 @@ -import $ from 'jquery'; import autocomplete from 'autocomplete.js'; +import { getJSON, fire } from '@utils'; const sources = [ { @@ -24,7 +24,7 @@ function selector(type) { function source(url) { return { source(query, callback) { - $.getJSON(url, { request: query }).then(callback); + getJSON(url, { request: query }).then(callback); }, templates: { suggestion({ label, mine }) { @@ -41,7 +41,7 @@ addEventListener('turbolinks:load', function() { for (let target of document.querySelectorAll(selector(type))) { let select = autocomplete(target, options, [source(url)]); select.on('autocomplete:selected', ({ target }, suggestion) => { - $(target).trigger('autocomplete:select', suggestion); + fire(target, 'autocomplete:select', suggestion); select.autocomplete.setVal(suggestion.label); }); } diff --git a/app/javascript/shared/rails-ujs-fix.js b/app/javascript/shared/rails-ujs-fix.js index a7cc7eb5e..f36330901 100644 --- a/app/javascript/shared/rails-ujs-fix.js +++ b/app/javascript/shared/rails-ujs-fix.js @@ -1,12 +1,13 @@ import Rails from 'rails-ujs'; import jQuery from 'jquery'; +import { delegate } from '@utils'; // We use `jQuery.active` in our capybara suit to wait for ajax requests. // Newer jQuery-less version of rails-ujs is breaking it. // We have to set `ajax:complete` listener on the same element as the one // we catch ajax:send on as by the end of the request // the old element may be removed from DOM. -Rails.delegate(document, '[data-remote]', 'ajax:send', ({ target }) => { +delegate('ajax:send', '[data-remote]', ({ target }) => { let callback = () => { jQuery.active--; target.removeEventListener('ajax:complete', callback); diff --git a/app/javascript/shared/remote-input.js b/app/javascript/shared/remote-input.js index d03e69640..e265a1835 100644 --- a/app/javascript/shared/remote-input.js +++ b/app/javascript/shared/remote-input.js @@ -1,7 +1,4 @@ -import Rails from 'rails-ujs'; -import debounce from 'debounce'; - -const { delegate, fire } = Rails; +import { delegate, fire, debounce } from '@utils'; const remote = 'data-remote'; const inputChangeSelector = `input[${remote}], textarea[${remote}]`; @@ -21,4 +18,4 @@ function isRemote(element) { return value && value !== 'false'; } -delegate(document, inputChangeSelector, 'input', debounce(handleRemote, 200)); +delegate('input', inputChangeSelector, debounce(handleRemote, 200)); From d18b1c8ddc0f5ba84e2ba534e0d2c782f6d29f06 Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Tue, 9 Oct 2018 11:43:25 +0200 Subject: [PATCH 05/10] Refactor form validation helpers --- app/javascript/new_design/form-validation.js | 23 ++++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/app/javascript/new_design/form-validation.js b/app/javascript/new_design/form-validation.js index 06b9c161c..9f0b74184 100644 --- a/app/javascript/new_design/form-validation.js +++ b/app/javascript/new_design/form-validation.js @@ -1,10 +1,19 @@ -import $ from 'jquery'; +import { delegate } from '@utils'; -$(document).on('blur keydown', 'input, textarea', () => { - $(this).addClass('touched'); +delegate('blur keydown', 'input, textarea', ({ target }) => { + touch(target); }); -$(document).on('click', 'input[type="submit"]:not([formnovalidate])', () => { - const $form = $(this).closest('form'); - $('input, textarea', $form).addClass('touched'); -}); +delegate( + 'click', + 'input[type="submit"]:not([formnovalidate])', + ({ target }) => { + let form = target.closest('form'); + let inputs = form ? form.querySelectorAll('input, textarea') : []; + [...inputs].forEach(touch); + } +); + +function touch({ classList }) { + classList.add('touched'); +} From 3897d4abf41395d64b641741b22776badb658aaa Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Tue, 9 Oct 2018 11:43:38 +0200 Subject: [PATCH 06/10] Refactor messagerie helpers --- app/javascript/new_design/messagerie.js | 24 +++++++----------------- app/javascript/shared/utils.js | 17 +++++++++++------ 2 files changed, 18 insertions(+), 23 deletions(-) diff --git a/app/javascript/new_design/messagerie.js b/app/javascript/new_design/messagerie.js index a7dd2bc39..91e9190db 100644 --- a/app/javascript/new_design/messagerie.js +++ b/app/javascript/new_design/messagerie.js @@ -1,27 +1,17 @@ -import $ from 'jquery'; +import { scrollTo, scrollToBottom } from '@utils'; export function scrollMessagerie() { - const $ul = $('.messagerie ul').first(); + const ul = document.querySelector('.messagerie ul'); - if ($ul.length) { - const $elementToScroll = $('.date.highlighted').first(); + if (ul) { + const elementToScroll = document.querySelector('.date.highlighted'); - if ($elementToScroll.length != 0) { - scrollTo($ul, $elementToScroll); + if (elementToScroll) { + scrollTo(ul, elementToScroll); } else { - scrollToBottom($ul); + scrollToBottom(ul); } } } -function scrollTo($container, $scrollTo) { - $container.scrollTop( - $scrollTo.offset().top - $container.offset().top + $container.scrollTop() - ); -} - -function scrollToBottom($container) { - $container.scrollTop($container.prop('scrollHeight')); -} - addEventListener('turbolinks:load', scrollMessagerie); diff --git a/app/javascript/shared/utils.js b/app/javascript/shared/utils.js index 8270f4d70..9b413e98b 100644 --- a/app/javascript/shared/utils.js +++ b/app/javascript/shared/utils.js @@ -37,15 +37,12 @@ export function getJSON(url, data, method = 'get') { } export function scrollTo(container, scrollTo) { - $(container).scrollTop( - $(scrollTo).offset().top - - $(container).offset().top + - $(container).scrollTop() - ); + container.scrollTop = + offset(scrollTo).top - offset(container).top + container.scrollTop; } export function scrollToBottom(container) { - $(container).scrollTop(container.scrollHeight); + container.scrollTop = container.scrollHeight; } export function on(selector, eventName, fn) { @@ -53,3 +50,11 @@ export function on(selector, eventName, fn) { element.addEventListener(eventName, event => fn(event, event.detail)) ); } + +function offset(element) { + const rect = element.getBoundingClientRect(); + return { + top: rect.top + document.body.scrollTop, + left: rect.left + document.body.scrollLeft + }; +} From 9d5ffba0687d3a6a1de64b30d5b7d692f2b15c8f Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Tue, 9 Oct 2018 11:43:51 +0200 Subject: [PATCH 07/10] Refactor state button helpers --- app/assets/stylesheets/new_design/motivation.scss | 1 - app/javascript/new_design/state-button.js | 10 +++++----- .../dossiers/_state_button_motivation.html.haml | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/app/assets/stylesheets/new_design/motivation.scss b/app/assets/stylesheets/new_design/motivation.scss index 52781f9b2..5adcbc78b 100644 --- a/app/assets/stylesheets/new_design/motivation.scss +++ b/app/assets/stylesheets/new_design/motivation.scss @@ -2,7 +2,6 @@ @import "constants"; .motivation { - display: none; padding: $default-padding; color: $black; width: 450px; diff --git a/app/javascript/new_design/state-button.js b/app/javascript/new_design/state-button.js index 0f0983a41..da47340fd 100644 --- a/app/javascript/new_design/state-button.js +++ b/app/javascript/new_design/state-button.js @@ -1,12 +1,12 @@ -import $ from 'jquery'; +import { show, hide } from '@utils'; export function showMotivation(event, state) { event.preventDefault(); - $(`.motivation.${state}`).show(); - $('.dropdown-items').hide(); + show(document.querySelector(`.motivation.${state}`)); + hide(document.querySelector('.dropdown-items')); } export function motivationCancel() { - $('.motivation').hide(); - $('.dropdown-items').show(); + document.querySelectorAll('.motivation').forEach(hide); + show(document.querySelector('.dropdown-items')); } diff --git a/app/views/new_gestionnaire/dossiers/_state_button_motivation.html.haml b/app/views/new_gestionnaire/dossiers/_state_button_motivation.html.haml index d72c793e7..99a6dfc88 100644 --- a/app/views/new_gestionnaire/dossiers/_state_button_motivation.html.haml +++ b/app/views/new_gestionnaire/dossiers/_state_button_motivation.html.haml @@ -1,4 +1,4 @@ -.motivation{ class: popup_class } +.motivation.hidden{ class: popup_class } %h3 %span.icon{ class: popup_class } #{popup_title} From 08d5e7d328828e4ebdf5fde3a94f3488c1edd2e1 Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Tue, 9 Oct 2018 11:44:02 +0200 Subject: [PATCH 08/10] Refactor toggle chart helpers --- app/javascript/new_design/toggle-chart.js | 32 ++++++++++------------- 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/app/javascript/new_design/toggle-chart.js b/app/javascript/new_design/toggle-chart.js index b51622402..2de8b6394 100644 --- a/app/javascript/new_design/toggle-chart.js +++ b/app/javascript/new_design/toggle-chart.js @@ -1,28 +1,24 @@ -import $ from 'jquery'; import Chartkick from 'chartkick'; +import { toggle } from '@utils'; export function toggleChart(event, chartClass) { - const nextSelectorItem = $(event.target), - nextChart = $(chartClass), - nextChartId = nextChart - .children() - .first() - .attr('id'), - currentSelectorItem = nextSelectorItem - .parent() - .find('.segmented-control-item-active'), - currentChart = nextSelectorItem - .parent() - .parent() - .find('.chart:not(.hidden)'); + const nextSelectorItem = event.target, + nextChart = document.querySelector(chartClass), + nextChartId = nextChart.children[0].id, + currentSelectorItem = nextSelectorItem.parentElement.querySelector( + '.segmented-control-item-active' + ), + currentChart = nextSelectorItem.parentElement.parentElement.querySelector( + '.chart:not(.hidden)' + ); // Change the current selector and the next selector states - currentSelectorItem.toggleClass('segmented-control-item-active'); - nextSelectorItem.toggleClass('segmented-control-item-active'); + currentSelectorItem.classList.toggle('segmented-control-item-active'); + nextSelectorItem.classList.toggle('segmented-control-item-active'); // Hide the currently shown chart and show the new one - currentChart.toggleClass('hidden'); - nextChart.toggleClass('hidden'); + toggle(currentChart); + toggle(nextChart); // Reflow needed, see https://github.com/highcharts/highcharts/issues/1979 Chartkick.charts[nextChartId].getChartObject().reflow(); From b79e77687e30c6c190517bd99eb7bfcb78c729fc Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Wed, 10 Oct 2018 14:53:59 +0200 Subject: [PATCH 09/10] Refactor avis helpers --- app/assets/stylesheets/new_design/avis.scss | 1 - app/javascript/new_design/avis.js | 4 ++-- app/views/new_gestionnaire/shared/avis/_form.html.haml | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/app/assets/stylesheets/new_design/avis.scss b/app/assets/stylesheets/new_design/avis.scss index 51930f4bc..0217f3d76 100644 --- a/app/assets/stylesheets/new_design/avis.scss +++ b/app/assets/stylesheets/new_design/avis.scss @@ -65,7 +65,6 @@ } .confidentiel-explanation { - display: none; font-size: 14px; color: $grey; margin-top: -$default-padding; diff --git a/app/javascript/new_design/avis.js b/app/javascript/new_design/avis.js index c35fdc6eb..99b4f869c 100644 --- a/app/javascript/new_design/avis.js +++ b/app/javascript/new_design/avis.js @@ -1,5 +1,5 @@ -import $ from 'jquery'; +import { toggle } from '@utils'; export function toggleCondidentielExplanation() { - $('.confidentiel-explanation').toggle(); + toggle(document.querySelector('.confidentiel-explanation')); } diff --git a/app/views/new_gestionnaire/shared/avis/_form.html.haml b/app/views/new_gestionnaire/shared/avis/_form.html.haml index c429b8103..29aefebfa 100644 --- a/app/views/new_gestionnaire/shared/avis/_form.html.haml +++ b/app/views/new_gestionnaire/shared/avis/_form.html.haml @@ -17,7 +17,7 @@ .confidentiel-wrapper = f.label :confidentiel, 'Cet avis est' = f.select :confidentiel, [['partagé avec les autres experts', false], ['confidentiel', true]], {}, onchange: "javascript:DS.toggleCondidentielExplanation(event);" - .confidentiel-explanation + .confidentiel-explanation.hidden Il ne sera pas affiché aux autres experts consultés mais sera visible par les instructeurs .send-wrapper = f.submit 'Demander un avis', class: 'button send' From 136031bea455b66afecf8704f1a64c5d3d4960e9 Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Tue, 9 Oct 2018 11:44:24 +0200 Subject: [PATCH 10/10] Remove jQuery import from new design --- app/javascript/packs/application.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/app/javascript/packs/application.js b/app/javascript/packs/application.js index 758b934fa..530b94bdf 100644 --- a/app/javascript/packs/application.js +++ b/app/javascript/packs/application.js @@ -4,7 +4,6 @@ import Rails from 'rails-ujs'; import ActiveStorage from '../shared/activestorage/ujs'; import Chartkick from 'chartkick'; import Highcharts from 'highcharts'; -import jQuery from 'jquery'; import '../shared/sentry'; import '../shared/rails-ujs-fix'; @@ -41,11 +40,6 @@ Rails.start(); Turbolinks.start(); ActiveStorage.start(); -// Disable jQuery-driven animations during tests -if (process.env['RAILS_ENV'] === 'test') { - jQuery.fx.off = true; -} - // Expose globals window.DS = window.DS || DS; window.Chartkick = Chartkick;