From a681564b39fca8ac7ba53f80292e6e6becda10e7 Mon Sep 17 00:00:00 2001 From: Xavier J Date: Wed, 21 Dec 2016 17:26:31 +0100 Subject: [PATCH 01/30] Add notification table and model --- app/models/dossier.rb | 1 + app/models/notification.rb | 4 ++++ app/views/backoffice/dossiers/_list.html.haml | 12 ++++++++++++ db/migrate/20161221153929_create_notification.rb | 16 ++++++++++++++++ db/schema.rb | 13 ++++++++++++- spec/models/dossier_spec.rb | 1 + spec/models/notification_spec.rb | 12 ++++++++++++ 7 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 app/models/notification.rb create mode 100644 db/migrate/20161221153929_create_notification.rb create mode 100644 spec/models/notification_spec.rb diff --git a/app/models/dossier.rb b/app/models/dossier.rb index 344a583e7..e0d7c2979 100644 --- a/app/models/dossier.rb +++ b/app/models/dossier.rb @@ -27,6 +27,7 @@ class Dossier < ActiveRecord::Base has_many :invites, dependent: :destroy has_many :invites_user, class_name: 'InviteUser', dependent: :destroy has_many :follows + has_many :notifications, dependent: :destroy belongs_to :procedure belongs_to :user diff --git a/app/models/notification.rb b/app/models/notification.rb new file mode 100644 index 000000000..3a48600cc --- /dev/null +++ b/app/models/notification.rb @@ -0,0 +1,4 @@ +class Notification < ActiveRecord::Base + belongs_to :dossier + +end diff --git a/app/views/backoffice/dossiers/_list.html.haml b/app/views/backoffice/dossiers/_list.html.haml index a06af02e0..db57cf6fd 100644 --- a/app/views/backoffice/dossiers/_list.html.haml +++ b/app/views/backoffice/dossiers/_list.html.haml @@ -1,5 +1,8 @@ %table#dossiers_list.table %thead + - if smart_listing.name.to_s == 'follow_dossiers' + %th + %i.fa.fa-bell - @facade_data_view.preference_list_dossiers_filter.each do |preference| %th{class: "col-md-#{preference.bootstrap_lg} col-lg-#{preference.bootstrap_lg}"} - if preference.table.to_s.include? 'champs' @@ -16,6 +19,15 @@ - unless smart_listing.empty? - smart_listing.collection.each do |dossier| %tr{id: "tr_dossier_#{dossier.id}", 'data-dossier_url' => backoffice_dossier_url(id: dossier.id)} + - if smart_listing.name.to_s == 'follow_dossiers' + %td.center + - total_notif = dossier.notifications.count + - if total_notif == 0 + .badge.progress-bar-default + = total_notif + - else + .badge.progress-bar-danger + = total_notif - @facade_data_view.preference_list_dossiers_filter.each_with_index do |preference, index| %td - if preference.table.nil? || preference.table.empty? diff --git a/db/migrate/20161221153929_create_notification.rb b/db/migrate/20161221153929_create_notification.rb new file mode 100644 index 000000000..745086412 --- /dev/null +++ b/db/migrate/20161221153929_create_notification.rb @@ -0,0 +1,16 @@ +class CreateNotification < ActiveRecord::Migration[5.0] + def change + create_table :notifications do |t| + + t.boolean :already_read, default: false + t.string :liste, array: true + t.boolean :multiple, default: false + t.string :type_notif + t.datetime :created_at + t.datetime :updated_at + + end + + add_belongs_to :notifications, :dossier + end +end diff --git a/db/schema.rb b/db/schema.rb index dbbb43529..924830524 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: 20161205110427) do +ActiveRecord::Schema.define(version: 20161221153929) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -249,6 +249,17 @@ ActiveRecord::Schema.define(version: 20161205110427) do t.index ["procedure_id"], name: "index_module_api_cartos_on_procedure_id", unique: true, using: :btree end + create_table "notifications", force: :cascade do |t| + t.boolean "already_read", default: false + t.string "liste", array: true + t.boolean "multiple", default: false + t.string "type_notif" + t.datetime "created_at" + t.datetime "updated_at" + t.integer "dossier_id" + t.index ["dossier_id"], name: "index_notifications_on_dossier_id", using: :btree + end + create_table "pieces_justificatives", force: :cascade do |t| t.string "content" t.integer "dossier_id" diff --git a/spec/models/dossier_spec.rb b/spec/models/dossier_spec.rb index 5fe22ff6e..4349748ad 100644 --- a/spec/models/dossier_spec.rb +++ b/spec/models/dossier_spec.rb @@ -27,6 +27,7 @@ describe Dossier do it { is_expected.to belong_to(:user) } it { is_expected.to have_many(:invites) } it { is_expected.to have_many(:follows) } + it { is_expected.to have_many(:notifications) } end describe 'delegation' do diff --git a/spec/models/notification_spec.rb b/spec/models/notification_spec.rb new file mode 100644 index 000000000..8adf11ab2 --- /dev/null +++ b/spec/models/notification_spec.rb @@ -0,0 +1,12 @@ +require 'spec_helper' + +describe Notification do + it { is_expected.to have_db_column(:already_read) } + it { is_expected.to have_db_column(:liste) } + it { is_expected.to have_db_column(:multiple) } + it { is_expected.to have_db_column(:type_notif) } + it { is_expected.to have_db_column(:created_at) } + it { is_expected.to have_db_column(:updated_at) } + + it { is_expected.to belong_to(:dossier) } +end From 54fbe367c0b3ef6735b4fa436e0a4b11692fe3ac Mon Sep 17 00:00:00 2001 From: Xavier J Date: Thu, 22 Dec 2016 20:40:23 +0100 Subject: [PATCH 02/30] Add notifications when user post a comment --- app/controllers/commentaires_controller.rb | 19 +++++++---- app/models/notification.rb | 4 +++ app/services/notification_service.rb | 33 +++++++++++++++++++ .../users/commentaires_controller_spec.rb | 4 +++ spec/factories/notification.rb | 12 +++++++ spec/services/notification_service_spec.rb | 29 ++++++++++++++++ 6 files changed, 94 insertions(+), 7 deletions(-) create mode 100644 app/services/notification_service.rb create mode 100644 spec/factories/notification.rb create mode 100644 spec/services/notification_service_spec.rb diff --git a/app/controllers/commentaires_controller.rb b/app/controllers/commentaires_controller.rb index 06c7edc19..a3cb762f5 100644 --- a/app/controllers/commentaires_controller.rb +++ b/app/controllers/commentaires_controller.rb @@ -1,9 +1,9 @@ class CommentairesController < ApplicationController def index @facade = DossierFacades.new( - params[:dossier_id], - (current_gestionnaire || current_user).email, - params[:champs_id] + params[:dossier_id], + (current_gestionnaire || current_user).email, + params[:champs_id] ) render layout: false rescue ActiveRecord::RecordNotFound @@ -48,12 +48,17 @@ class CommentairesController < ApplicationController end NotificationMailer.new_answer(@commentaire.dossier).deliver_now! if saved + redirect_to url_for(controller: 'backoffice/dossiers', action: :show, id: params['dossier_id']) - elsif current_user.email != @commentaire.dossier.user.email - invite = Invite.where(dossier: @commentaire.dossier, user: current_user).first - redirect_to url_for(controller: 'users/dossiers/invites', action: :show, id: invite.id) else - redirect_to url_for(controller: :recapitulatif, action: :show, dossier_id: params['dossier_id']) + NotificationService.new('commentaire', @commentaire.dossier.id).notify if saved + + if current_user.email != @commentaire.dossier.user.email + invite = Invite.where(dossier: @commentaire.dossier, user: current_user).first + redirect_to url_for(controller: 'users/dossiers/invites', action: :show, id: invite.id) + else + redirect_to url_for(controller: :recapitulatif, action: :show, dossier_id: params['dossier_id']) + end end end diff --git a/app/models/notification.rb b/app/models/notification.rb index 3a48600cc..a9cb87586 100644 --- a/app/models/notification.rb +++ b/app/models/notification.rb @@ -1,4 +1,8 @@ class Notification < ActiveRecord::Base belongs_to :dossier + enum type_notif: { + commentaire: 'commentaire' + } + end diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb new file mode 100644 index 000000000..7e5ad2bcb --- /dev/null +++ b/app/services/notification_service.rb @@ -0,0 +1,33 @@ +class NotificationService + + def initialize type_notif, dossier_id + @type_notif = type_notif + @dossier_id = dossier_id + + notification.liste.push text_for_notif + + self + end + + def notify + notification.save + end + + def notification + @notification ||= + begin + Notification.find_by! dossier_id: @dossier_id, already_read: false, type_notif: @type_notif + rescue ActiveRecord::RecordNotFound + Notification.new dossier_id: @dossier_id, type_notif: @type_notif, liste: [] + end + end + + def text_for_notif + case @type_notif + when 'commentaire' + "#{notification.liste.size + 1} nouveau(x) commentaire(s) déposé(s)." + else + 'Notification par défaut' + end + end +end \ No newline at end of file diff --git a/spec/controllers/users/commentaires_controller_spec.rb b/spec/controllers/users/commentaires_controller_spec.rb index 54edd2c4d..b03cc9225 100644 --- a/spec/controllers/users/commentaires_controller_spec.rb +++ b/spec/controllers/users/commentaires_controller_spec.rb @@ -28,6 +28,10 @@ describe Users::CommentairesController, type: :controller do subject end + + it 'Notification interne is create' do + expect { subject }.to change(Notification, :count).by (1) + end end context 'when document is upload whith a commentaire', vcr: {cassette_name: 'controllers_sers_commentaires_controller_upload_doc'} do diff --git a/spec/factories/notification.rb b/spec/factories/notification.rb new file mode 100644 index 000000000..8192f381b --- /dev/null +++ b/spec/factories/notification.rb @@ -0,0 +1,12 @@ +FactoryGirl.define do + factory :notification do + type_notif 'commentaire' + liste [] + + after(:create) do |notification, _evaluator| + unless notification.dossier + notification.dossier = create :dossier + end + end + end +end diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb new file mode 100644 index 000000000..d091c69b2 --- /dev/null +++ b/spec/services/notification_service_spec.rb @@ -0,0 +1,29 @@ +require 'spec_helper' + +describe NotificationService do + + describe '.notify' do + let(:dossier) { create :dossier } + let(:service) { described_class.new type_notif, dossier.id } + + subject { service.notify } + + context 'when is the first notification for dossier_id and type_notif and alread_read is false' do + let(:type_notif) { 'commentaire' } + + it { expect { subject }.to change(Notification, :count).by (1) } + + context 'when is not the first notification' do + before do + create :notification, dossier: dossier, type_notif: type_notif + end + + it { expect { subject }.to change(Notification, :count).by (0) } + end + end + end + + describe 'text_for_notif' do + pending + end +end \ No newline at end of file From 07495ff9ba058a69d1653c88fbbfaf7e5b840232 Mon Sep 17 00:00:00 2001 From: Xavier J Date: Thu, 22 Dec 2016 21:25:55 +0100 Subject: [PATCH 03/30] Ajust UI for notifications --- app/views/backoffice/dossiers/_list.html.haml | 2 +- app/views/layouts/_navbar.html.haml | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/views/backoffice/dossiers/_list.html.haml b/app/views/backoffice/dossiers/_list.html.haml index db57cf6fd..e5b60cdee 100644 --- a/app/views/backoffice/dossiers/_list.html.haml +++ b/app/views/backoffice/dossiers/_list.html.haml @@ -26,7 +26,7 @@ .badge.progress-bar-default = total_notif - else - .badge.progress-bar-danger + .badge.progress-bar-warning = total_notif - @facade_data_view.preference_list_dossiers_filter.each_with_index do |preference, index| %td diff --git a/app/views/layouts/_navbar.html.haml b/app/views/layouts/_navbar.html.haml index 415f6bbda..908ccc621 100644 --- a/app/views/layouts/_navbar.html.haml +++ b/app/views/layouts/_navbar.html.haml @@ -5,6 +5,8 @@ = image_tag('marianne_small.png', class: 'logo') %div.col-lg-6.no-padding#tps-title TPS + .badge.progress-bar-danger + = Notification.where(already_read: false).count %div.col-lg-10.col-md-10.no-padding %div#navbar-body From f98bb90f08144e37742da83b4a8113fc33107c30 Mon Sep 17 00:00:00 2001 From: Xavier J Date: Thu, 22 Dec 2016 21:49:31 +0100 Subject: [PATCH 04/30] Bootstrap Action Cable and Unicorn --- Gemfile | 5 + Gemfile.lock | 6 + app/assets/javascripts/cable.js | 13 +++ app/channels/application_cable/channel.rb | 5 + app/channels/application_cable/connection.rb | 5 + app/jobs/application_job.rb | 2 + app/models/application_record.rb | 3 + app/views/layouts/application.html.haml | 1 + config.ru | 4 + config/cable.yml | 10 ++ config/environments/development.rb | 2 +- config/routes.rb | 2 + config/unicorn.rb | 109 +++++++++++++++++++ 13 files changed, 166 insertions(+), 1 deletion(-) create mode 100644 app/assets/javascripts/cable.js create mode 100644 app/channels/application_cable/channel.rb create mode 100644 app/channels/application_cable/connection.rb create mode 100644 app/jobs/application_job.rb create mode 100644 app/models/application_record.rb create mode 100644 config/cable.yml create mode 100644 config/unicorn.rb diff --git a/Gemfile b/Gemfile index bb142816d..6484c2565 100644 --- a/Gemfile +++ b/Gemfile @@ -3,6 +3,9 @@ source 'https://rubygems.org' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' gem 'rails', '5.0.0.1' +gem 'actioncable', '5.0.0.1' +gem 'redis' + # Use SCSS for stylesheets gem 'sass-rails', '~> 5.0' # Use Uglifier as compressor for JavaScript assets @@ -116,6 +119,8 @@ group :development do # Access an IRB console on exception pages or by using <%= console %> in views gem 'web-console' + + gem 'rack-handlers' end group :development, :test do diff --git a/Gemfile.lock b/Gemfile.lock index 3d8969e9e..ebf23e02c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -417,6 +417,8 @@ GEM pry (~> 0.10) public_suffix (2.0.4) rack (2.0.1) + rack-handlers (0.7.3) + rack rack-oauth2 (1.4.0) activesupport (>= 2.3) attr_required (>= 0.0.5) @@ -465,6 +467,7 @@ GEM nokogiri (~> 1.5) trollop (~> 2.1) rdoc (4.3.0) + redis (3.3.0) ref (2.0.0) request_store (1.3.1) responders (2.3.0) @@ -624,6 +627,7 @@ PLATFORMS ruby DEPENDENCIES + actioncable (= 5.0.0.1) active_model_serializers apipie-rails as_csv @@ -665,9 +669,11 @@ DEPENDENCIES pg poltergeist pry-byebug + rack-handlers railroady rails (= 5.0.0.1) rails-controller-testing + redis rest-client rgeo-geojson rspec-rails (~> 3.0) diff --git a/app/assets/javascripts/cable.js b/app/assets/javascripts/cable.js new file mode 100644 index 000000000..9139c80fd --- /dev/null +++ b/app/assets/javascripts/cable.js @@ -0,0 +1,13 @@ +// Action Cable provides the framework to deal with WebSockets in Rails. +// You can generate new channels where WebSocket features live using the rails generate channel command. +// +//= require action_cable +//= require_self +//= require_tree ./channels + +(function() { + this.App || (this.App = {}); + + App.cable = ActionCable.createConsumer(); + +}).call(this); diff --git a/app/channels/application_cable/channel.rb b/app/channels/application_cable/channel.rb new file mode 100644 index 000000000..d56fa30f4 --- /dev/null +++ b/app/channels/application_cable/channel.rb @@ -0,0 +1,5 @@ +# Be sure to restart your server when you modify this file. Action Cable runs in a loop that does not support auto reloading. +module ApplicationCable + class Channel < ActionCable::Channel::Base + end +end diff --git a/app/channels/application_cable/connection.rb b/app/channels/application_cable/connection.rb new file mode 100644 index 000000000..b4f41389a --- /dev/null +++ b/app/channels/application_cable/connection.rb @@ -0,0 +1,5 @@ +# Be sure to restart your server when you modify this file. Action Cable runs in a loop that does not support auto reloading. +module ApplicationCable + class Connection < ActionCable::Connection::Base + end +end diff --git a/app/jobs/application_job.rb b/app/jobs/application_job.rb new file mode 100644 index 000000000..a009ace51 --- /dev/null +++ b/app/jobs/application_job.rb @@ -0,0 +1,2 @@ +class ApplicationJob < ActiveJob::Base +end diff --git a/app/models/application_record.rb b/app/models/application_record.rb new file mode 100644 index 000000000..10a4cba84 --- /dev/null +++ b/app/models/application_record.rb @@ -0,0 +1,3 @@ +class ApplicationRecord < ActiveRecord::Base + self.abstract_class = true +end diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index cdb69731d..6cfc3ab0a 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -9,6 +9,7 @@ = javascript_include_tag 'application', 'data-turbolinks-track' => true = csrf_meta_tags + = action_cable_meta_tag %body = render partial: 'layouts/support_navigator_banner' #beta{class:(Rails.env == 'production' ? '' : 'beta_staging')} diff --git a/config.ru b/config.ru index bd83b2541..584d0390c 100644 --- a/config.ru +++ b/config.ru @@ -1,4 +1,8 @@ # This file is used by Rack-based servers to start the application. require ::File.expand_path('../config/environment', __FILE__) + +# Action Cable requires that all classes are loaded in advance +Rails.application.eager_load! + run Rails.application diff --git a/config/cable.yml b/config/cable.yml new file mode 100644 index 000000000..1aeb76f7c --- /dev/null +++ b/config/cable.yml @@ -0,0 +1,10 @@ +production: + adapter: redis + url: redis://localhost:6379 + +development: + adapter: redis + url: redis://localhost:6379 + +test: + adapter: async diff --git a/config/environments/development.rb b/config/environments/development.rb index f7174bfa2..4b96a6c33 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -45,5 +45,5 @@ Rails.application.configure do # Raises error for missing translations # config.action_view.raise_on_missing_translations = true - + config.action_cable.url = "ws://localhost:3000/cable" end diff --git a/config/routes.rb b/config/routes.rb index 58d2811dc..aaef99490 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -202,4 +202,6 @@ Rails.application.routes.draw do end apipie + + mount ActionCable.server => '/cable' end diff --git a/config/unicorn.rb b/config/unicorn.rb new file mode 100644 index 000000000..88a5d746a --- /dev/null +++ b/config/unicorn.rb @@ -0,0 +1,109 @@ +# Sample verbose configuration file for Unicorn (not Rack) +# +# This configuration file documents many features of Unicorn +# that may not be needed for some applications. See +# http://unicorn.bogomips.org/examples/unicorn.conf.minimal.rb +# for a much simpler configuration file. +# +# See http://unicorn.bogomips.org/Unicorn/Configurator.html for complete +# documentation. + + + +# Use at least one worker per core if you're on a dedicated server, +# more will usually help for _short_ waits on databases/caches. +worker_processes 2 + +# Since Unicorn is never exposed to outside clients, it does not need to +# run on the standard HTTP port (80), there is no reason to start Unicorn +# as root unless it's from system init scripts. +# If running the master process as root and the workers as an unprivileged +# user, do this to switch euid/egid in the workers (also chowns logs): +# user "unprivileged_user", "unprivileged_group" + +# Help ensure your application will always spawn in the symlinked +# "current" directory that Capistrano sets up. + +# listen on both a Unix domain socket and a TCP port, +# we use a shorter backlog for quicker failover when busy +listen "127.0.0.1:3000", :tcp_nopush => true + +# nuke workers after 30 seconds instead of 60 seconds (the default) +timeout 30 + +# By default, the Unicorn logger will write to stderr. +# Additionally, ome applications/frameworks log to stderr or stdout, +# so prevent them from going to /dev/null when daemonized here: + +# combine Ruby 2.0.0dev or REE with "preload_app true" for memory savings +# http://rubyenterpriseedition.com/faq.html#adapt_apps_for_cow +preload_app true +GC.respond_to?(:copy_on_write_friendly=) and + GC.copy_on_write_friendly = true + +# Enable this flag to have unicorn test client connections by writing the +# beginning of the HTTP headers before calling the application. This +# prevents calling the application for connections that have disconnected +# while queued. This is only guaranteed to detect clients on the same +# host unicorn runs on, and unlikely to detect disconnects even on a +# fast LAN. +check_client_connection false + +# local variable to guard against running a hook multiple times +run_once = true + + +before_fork do |server, worker| + # the following is highly recomended for Rails + "preload_app true" + # as there's no need for the master process to hold a connection + defined?(ActiveRecord::Base) and + ActiveRecord::Base.connection.disconnect! + + # Occasionally, it may be necessary to run non-idempotent code in the + # master before forking. Keep in mind the above disconnect! example + # is idempotent and does not need a guard. + if run_once + # do_something_once_here ... + run_once = false # prevent from firing again + end + + # The following is only recommended for memory/DB-constrained + # installations. It is not needed if your system can house + # twice as many worker_processes as you have configured. + # + # # This allows a new master process to incrementally + # # phase out the old master process with SIGTTOU to avoid a + # # thundering herd (especially in the "preload_app false" case) + # # when doing a transparent upgrade. The last worker spawned + # # will then kill off the old master process with a SIGQUIT. + old_pid = "#{server.config[:pid]}.oldbin" + if old_pid != server.pid + begin + sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU + Process.kill(sig, File.read(old_pid).to_i) + rescue Errno::ENOENT, Errno::ESRCH + end + end + # + # Throttle the master from forking too quickly by sleeping. Due + # to the implementation of standard Unix signal handlers, this + # helps (but does not completely) prevent identical, repeated signals + # from being lost when the receiving process is busy. + sleep 1 +end + +after_fork do |server, worker| + # per-process listener ports for debugging/admin/migrations + # addr = "127.0.0.1:#{9293 + worker.nr}" + # server.listen(addr, :tries => -1, :delay => 5, :tcp_nopush => true) + + # the following is *required* for Rails + "preload_app true", + defined?(ActiveRecord::Base) and + ActiveRecord::Base.establish_connection + + # if preload_app is true, then you may also want to check and + # restart any other shared sockets/descriptors such as Memcached, + # and Redis. TokyoCabinet file handles are safe to reuse + # between any number of forked children (assuming your kernel + # correctly implements pread()/pwrite() system calls) +end From c533bb0a88fbbf3ac456476ae23a7b6e4f2958f7 Mon Sep 17 00:00:00 2001 From: Xavier J Date: Thu, 22 Dec 2016 22:27:02 +0100 Subject: [PATCH 05/30] TEST : First implementation of notification with Action Cable : alert message --- .../javascripts/channels/notifications.js | 23 +++++++++++++++++++ .../stylesheets/notification_alert.scss | 12 ++++++++++ app/channels/notifications_channel.rb | 5 ++++ app/models/notification.rb | 6 +++++ app/views/layouts/_navbar.html.haml | 2 -- .../layouts/_notifications_alert.html.haml | 1 + app/views/layouts/application.html.haml | 1 + 7 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 app/assets/javascripts/channels/notifications.js create mode 100644 app/assets/stylesheets/notification_alert.scss create mode 100644 app/channels/notifications_channel.rb create mode 100644 app/views/layouts/_notifications_alert.html.haml diff --git a/app/assets/javascripts/channels/notifications.js b/app/assets/javascripts/channels/notifications.js new file mode 100644 index 000000000..a766b8cbf --- /dev/null +++ b/app/assets/javascripts/channels/notifications.js @@ -0,0 +1,23 @@ +App.messages = App.cable.subscriptions.create('NotificationsChannel', { + received: function (data) { + + if (window.location.href.indexOf('backoffice') !== -1) { + $("#notification_alert").html(data['message']); + slideIn_notification_alert(); + } + } +}); + +function slideIn_notification_alert (){ + $("#notification_alert").animate({ + right: '20px' + }, 250); + + setTimeout(slideOut_notification_alert, 3500); +} + +function slideOut_notification_alert (){ + $("#notification_alert").animate({ + right: '-250px' + }, 200); +} \ No newline at end of file diff --git a/app/assets/stylesheets/notification_alert.scss b/app/assets/stylesheets/notification_alert.scss new file mode 100644 index 000000000..caf95bdf9 --- /dev/null +++ b/app/assets/stylesheets/notification_alert.scss @@ -0,0 +1,12 @@ +#notification_alert { + position: fixed; + top: 20px; + right: -250px; + + z-index: 1000; + + width: 250px; + height: 80px; + + border: solid black 1px; +} \ No newline at end of file diff --git a/app/channels/notifications_channel.rb b/app/channels/notifications_channel.rb new file mode 100644 index 000000000..a57c0f242 --- /dev/null +++ b/app/channels/notifications_channel.rb @@ -0,0 +1,5 @@ +class NotificationsChannel < ApplicationCable::Channel + def subscribed + stream_from 'notifications' + end +end \ No newline at end of file diff --git a/app/models/notification.rb b/app/models/notification.rb index a9cb87586..9abe292c1 100644 --- a/app/models/notification.rb +++ b/app/models/notification.rb @@ -1,8 +1,14 @@ class Notification < ActiveRecord::Base belongs_to :dossier + after_save :broadcast_notification + enum type_notif: { commentaire: 'commentaire' } + def broadcast_notification + ActionCable.server.broadcast 'notifications', + message: "Nouveau commentaire posté sur le dossier #{self.dossier.id}" + end end diff --git a/app/views/layouts/_navbar.html.haml b/app/views/layouts/_navbar.html.haml index 908ccc621..415f6bbda 100644 --- a/app/views/layouts/_navbar.html.haml +++ b/app/views/layouts/_navbar.html.haml @@ -5,8 +5,6 @@ = image_tag('marianne_small.png', class: 'logo') %div.col-lg-6.no-padding#tps-title TPS - .badge.progress-bar-danger - = Notification.where(already_read: false).count %div.col-lg-10.col-md-10.no-padding %div#navbar-body diff --git a/app/views/layouts/_notifications_alert.html.haml b/app/views/layouts/_notifications_alert.html.haml new file mode 100644 index 000000000..372fe7497 --- /dev/null +++ b/app/views/layouts/_notifications_alert.html.haml @@ -0,0 +1 @@ +#notification_alert.alert.alert-success diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index 6cfc3ab0a..3b742d11c 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -50,6 +50,7 @@ %i.fa.fa-times{style:'position: fixed; top: 10; right: 30; color: white;'} = render partial: 'layouts/switch_devise_profile_module' + = render partial: 'layouts/notifications_alert' = render partial: 'layouts/footer', locals: {main_container_size: main_container_size} = render partial: 'layouts/google_analytics' From 4c9c898a69079f27c2de72a8ff8e0492d7074f0a Mon Sep 17 00:00:00 2001 From: JC Date: Mon, 26 Dec 2016 10:56:48 +0100 Subject: [PATCH 06/30] Feature test about clonning procedures --- app/views/admin/procedures/_list.html.haml | 2 +- spec/features/admin/procedure_cloning_spec.rb | 29 +++++++++++++++++++ .../features/admin/procedure_creation_spec.rb | 2 +- 3 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 spec/features/admin/procedure_cloning_spec.rb diff --git a/app/views/admin/procedures/_list.html.haml b/app/views/admin/procedures/_list.html.haml index d9d054d03..31879e2f6 100644 --- a/app/views/admin/procedures/_list.html.haml +++ b/app/views/admin/procedures/_list.html.haml @@ -19,7 +19,7 @@ %td = procedure.created_at_fr %td - = link_to('Cloner', admin_procedure_clone_path(procedure.id), 'data-method' => :put, class: 'btn-sm btn-primary') + = link_to('Cloner', admin_procedure_clone_path(procedure.id), 'data-method' => :put, class: 'btn-sm btn-primary clone-btn') - unless procedure.published? || procedure.archived? = link_to('X', url_for(controller: 'admin/procedures', action: :destroy, id: procedure.id), 'data-method' => :delete, class: 'btn-sm btn-danger') diff --git a/spec/features/admin/procedure_cloning_spec.rb b/spec/features/admin/procedure_cloning_spec.rb new file mode 100644 index 000000000..78e13045a --- /dev/null +++ b/spec/features/admin/procedure_cloning_spec.rb @@ -0,0 +1,29 @@ +require 'spec_helper' + +feature 'As an administrateur I wanna clone a procedure', js: true do + + let(:administrateur) { create(:administrateur) } + + before do + login_as administrateur, scope: :administrateur + visit root_path + end + + context 'Cloning procedure' do + + before 'Create procedure' do + page.find_by_id('new-procedure').click + fill_in 'procedure_libelle', with: 'libelle de la procedure' + page.execute_script("$('#procedure_description').data('wysihtml5').editor.setValue('description de la procedure')") + page.find_by_id('save-procedure').click + end + + scenario 'Cloning' do + visit admin_procedures_draft_path + expect(page.find_by_id('procedures')['data-item-count']).to eq('1') + page.all('.clone-btn').first.click + visit admin_procedures_draft_path + expect(page.find_by_id('procedures')['data-item-count']).to eq('2') + end + end +end diff --git a/spec/features/admin/procedure_creation_spec.rb b/spec/features/admin/procedure_creation_spec.rb index 49f033bc0..c123ad1fc 100644 --- a/spec/features/admin/procedure_creation_spec.rb +++ b/spec/features/admin/procedure_creation_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -feature 'as an administrateur I wanna create a new procedure', js: true do +feature 'As an administrateur I wanna create a new procedure', js: true do let(:administrateur) { create(:administrateur) } From 5eaa2941ad36a754fbf77e8df7b61a9298afe52f Mon Sep 17 00:00:00 2001 From: Xavier J Date: Mon, 26 Dec 2016 11:08:53 +0100 Subject: [PATCH 07/30] Move commentaire creation to model --- app/controllers/commentaires_controller.rb | 2 -- app/models/commentaire.rb | 8 ++++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/app/controllers/commentaires_controller.rb b/app/controllers/commentaires_controller.rb index a3cb762f5..cdf3cb747 100644 --- a/app/controllers/commentaires_controller.rb +++ b/app/controllers/commentaires_controller.rb @@ -51,8 +51,6 @@ class CommentairesController < ApplicationController redirect_to url_for(controller: 'backoffice/dossiers', action: :show, id: params['dossier_id']) else - NotificationService.new('commentaire', @commentaire.dossier.id).notify if saved - if current_user.email != @commentaire.dossier.user.email invite = Invite.where(dossier: @commentaire.dossier, user: current_user).first redirect_to url_for(controller: 'users/dossiers/invites', action: :show, id: invite.id) diff --git a/app/models/commentaire.rb b/app/models/commentaire.rb index 463285482..2a785da37 100644 --- a/app/models/commentaire.rb +++ b/app/models/commentaire.rb @@ -4,7 +4,15 @@ class Commentaire < ActiveRecord::Base belongs_to :piece_justificative + after_save :internal_notification + def header "#{email}, " + created_at.localtime.strftime('%d %b %Y %H:%M') end + + private + + def internal_notification + NotificationService.new('commentaire', self.dossier.id).notify + end end From 6ed91073c4377d770d9500709265b6a570c5ce7d Mon Sep 17 00:00:00 2001 From: Xavier J Date: Mon, 26 Dec 2016 11:33:12 +0100 Subject: [PATCH 08/30] Add notification for cerfa --- app/models/cerfa.rb | 8 ++++++++ app/models/notification.rb | 13 +++++++------ app/services/notification_service.rb | 2 ++ .../users/description_controller_shared_example.rb | 7 +++++++ 4 files changed, 24 insertions(+), 6 deletions(-) diff --git a/app/models/cerfa.rb b/app/models/cerfa.rb index 0022ad244..184060706 100644 --- a/app/models/cerfa.rb +++ b/app/models/cerfa.rb @@ -5,6 +5,8 @@ class Cerfa < ActiveRecord::Base mount_uploader :content, CerfaUploader validates :content, :file_size => {:maximum => 20.megabytes} + after_save :internal_notification + def empty? content.blank? end @@ -18,4 +20,10 @@ class Cerfa < ActiveRecord::Base end end end + + private + + def internal_notification + NotificationService.new('cerfa', self.dossier.id).notify + end end \ No newline at end of file diff --git a/app/models/notification.rb b/app/models/notification.rb index 9abe292c1..75396be4b 100644 --- a/app/models/notification.rb +++ b/app/models/notification.rb @@ -1,14 +1,15 @@ class Notification < ActiveRecord::Base belongs_to :dossier - after_save :broadcast_notification + # after_save :broadcast_notification enum type_notif: { - commentaire: 'commentaire' + commentaire: 'commentaire', + cerfa: 'cerfa' } - def broadcast_notification - ActionCable.server.broadcast 'notifications', - message: "Nouveau commentaire posté sur le dossier #{self.dossier.id}" - end + # def broadcast_notification + # ActionCable.server.broadcast 'notifications', + # message: "Nouveau commentaire posté sur le dossier #{self.dossier.id}" + # end end diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb index 7e5ad2bcb..d4f672a18 100644 --- a/app/services/notification_service.rb +++ b/app/services/notification_service.rb @@ -26,6 +26,8 @@ class NotificationService case @type_notif when 'commentaire' "#{notification.liste.size + 1} nouveau(x) commentaire(s) déposé(s)." + when 'cerfa' + "Un nouveau formulaire a été déposé." else 'Notification par défaut' end diff --git a/spec/controllers/users/description_controller_shared_example.rb b/spec/controllers/users/description_controller_shared_example.rb index a751f08e2..f74f8e04b 100644 --- a/spec/controllers/users/description_controller_shared_example.rb +++ b/spec/controllers/users/description_controller_shared_example.rb @@ -145,6 +145,13 @@ shared_examples 'description_controller_spec' do end context 'Quand la procédure accepte les CERFA' do + subject { post :create, params: {dossier_id: dossier_id, + cerfa_pdf: cerfa_pdf} } + + it 'Notification interne is create' do + expect { subject }.to change(Notification, :count).by (1) + end + context 'Sauvegarde du CERFA PDF', vcr: {cassette_name: 'controllers_users_description_controller_save_cerfa'} do before do post :create, params: {dossier_id: dossier_id, From e5768b67989cd6d3c3f756d40baf642f9e3391b8 Mon Sep 17 00:00:00 2001 From: Xavier J Date: Mon, 26 Dec 2016 11:42:02 +0100 Subject: [PATCH 09/30] Add notification for piece justificative --- app/models/notification.rb | 3 ++- app/models/piece_justificative.rb | 8 ++++++++ app/services/notification_service.rb | 9 ++++++--- .../users/description_controller_shared_example.rb | 4 ++++ 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/app/models/notification.rb b/app/models/notification.rb index 75396be4b..edd0ab23d 100644 --- a/app/models/notification.rb +++ b/app/models/notification.rb @@ -5,7 +5,8 @@ class Notification < ActiveRecord::Base enum type_notif: { commentaire: 'commentaire', - cerfa: 'cerfa' + cerfa: 'cerfa', + piece_justificative: 'piece_justificative' } # def broadcast_notification diff --git a/app/models/piece_justificative.rb b/app/models/piece_justificative.rb index e1a0df9c8..405871a38 100644 --- a/app/models/piece_justificative.rb +++ b/app/models/piece_justificative.rb @@ -13,6 +13,8 @@ class PieceJustificative < ActiveRecord::Base validates :content, :file_size => {:maximum => 20.megabytes} validates :content, presence: true, allow_blank: false, allow_nil: false + after_save :internal_notification + def empty? content.blank? end @@ -43,4 +45,10 @@ class PieceJustificative < ActiveRecord::Base image/jpeg " end + + private + + def internal_notification + NotificationService.new('piece_justificative', self.dossier.id, self.libelle).notify + end end diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb index d4f672a18..fe46c0cc3 100644 --- a/app/services/notification_service.rb +++ b/app/services/notification_service.rb @@ -1,10 +1,11 @@ class NotificationService - def initialize type_notif, dossier_id + def initialize type_notif, dossier_id, attribut_change='' @type_notif = type_notif @dossier_id = dossier_id - notification.liste.push text_for_notif + notification.liste.push text_for_notif attribut_change + notification.liste = notification.liste.uniq self end @@ -22,12 +23,14 @@ class NotificationService end end - def text_for_notif + def text_for_notif attribut='' case @type_notif when 'commentaire' "#{notification.liste.size + 1} nouveau(x) commentaire(s) déposé(s)." when 'cerfa' "Un nouveau formulaire a été déposé." + when 'piece_justificative' + attribut else 'Notification par défaut' end diff --git a/spec/controllers/users/description_controller_shared_example.rb b/spec/controllers/users/description_controller_shared_example.rb index f74f8e04b..c08c8bbd2 100644 --- a/spec/controllers/users/description_controller_shared_example.rb +++ b/spec/controllers/users/description_controller_shared_example.rb @@ -299,6 +299,10 @@ shared_examples 'description_controller_spec' do sign_in guest end + it 'Notification interne is create' do + expect { subject }.to change(Notification, :count).by (1) + end + context 'when PJ have no documents' do it { expect(dossier.pieces_justificatives.size).to eq 0 } From 33c1a12b84b188ba73d2d3f73e3f22fcdebea73a Mon Sep 17 00:00:00 2001 From: Xavier J Date: Mon, 26 Dec 2016 11:47:51 +0100 Subject: [PATCH 10/30] Add notification for champs --- app/models/champ.rb | 14 +++++++++++--- app/models/notification.rb | 3 ++- app/services/notification_service.rb | 2 ++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/app/models/champ.rb b/app/models/champ.rb index f6ba23268..0016b1c45 100644 --- a/app/models/champ.rb +++ b/app/models/champ.rb @@ -5,6 +5,8 @@ class Champ < ActiveRecord::Base delegate :libelle, :type_champ, :order_place, :mandatory, :description, :drop_down_list, to: :type_de_champ + after_save :internal_notification + def mandatory? mandatory end @@ -36,14 +38,20 @@ class Champ < ActiveRecord::Base end def self.regions - JSON.parse(Carto::GeoAPI::Driver.regions).sort_by{|e| e['nom']}.inject([]){|acc, liste| acc.push(liste['nom']) } + JSON.parse(Carto::GeoAPI::Driver.regions).sort_by { |e| e['nom'] }.inject([]) { |acc, liste| acc.push(liste['nom']) } end def self.departements - JSON.parse(Carto::GeoAPI::Driver.departements).inject([]){|acc, liste| acc.push(liste['code'] + ' - ' + liste['nom']) }.push('99 - Étranger') + JSON.parse(Carto::GeoAPI::Driver.departements).inject([]) { |acc, liste| acc.push(liste['code'] + ' - ' + liste['nom']) }.push('99 - Étranger') end def self.pays - JSON.parse(Carto::GeoAPI::Driver.pays).inject([]){|acc, liste| acc.push(liste['nom']) } + JSON.parse(Carto::GeoAPI::Driver.pays).inject([]) { |acc, liste| acc.push(liste['nom']) } + end + + private + + def internal_notification + NotificationService.new('champs', self.dossier.id, self.libelle).notify end end diff --git a/app/models/notification.rb b/app/models/notification.rb index edd0ab23d..9bf44e61a 100644 --- a/app/models/notification.rb +++ b/app/models/notification.rb @@ -6,7 +6,8 @@ class Notification < ActiveRecord::Base enum type_notif: { commentaire: 'commentaire', cerfa: 'cerfa', - piece_justificative: 'piece_justificative' + piece_justificative: 'piece_justificative', + champs: 'champs' } # def broadcast_notification diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb index fe46c0cc3..1fb438b42 100644 --- a/app/services/notification_service.rb +++ b/app/services/notification_service.rb @@ -31,6 +31,8 @@ class NotificationService "Un nouveau formulaire a été déposé." when 'piece_justificative' attribut + when 'champs' + attribut else 'Notification par défaut' end From 33362d1a525f1f80d3d0d1749f895a709cdf63e9 Mon Sep 17 00:00:00 2001 From: Xavier J Date: Mon, 26 Dec 2016 11:57:08 +0100 Subject: [PATCH 11/30] Add notification for submitted state --- app/models/dossier.rb | 9 +++++++++ app/models/notification.rb | 3 ++- app/services/notification_service.rb | 2 ++ spec/controllers/users/recapitulatif_controller_spec.rb | 4 ++++ 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/app/models/dossier.rb b/app/models/dossier.rb index e0d7c2979..8680dc64c 100644 --- a/app/models/dossier.rb +++ b/app/models/dossier.rb @@ -42,6 +42,7 @@ class Dossier < ActiveRecord::Base after_save :build_default_champs, if: Proc.new { procedure_id_changed? } after_save :build_default_individual, if: Proc.new { procedure.for_individual? } + after_save :internal_notification validates :user, presence: true @@ -327,4 +328,12 @@ class Dossier < ActiveRecord::Base def invite_by_user? email (invites_user.pluck :email).include? email end + + private + + def internal_notification + if state_changed? && state == 'submitted' + NotificationService.new('submitted', self.id).notify + end + end end diff --git a/app/models/notification.rb b/app/models/notification.rb index 9bf44e61a..be256f25a 100644 --- a/app/models/notification.rb +++ b/app/models/notification.rb @@ -7,7 +7,8 @@ class Notification < ActiveRecord::Base commentaire: 'commentaire', cerfa: 'cerfa', piece_justificative: 'piece_justificative', - champs: 'champs' + champs: 'champs', + submitted: 'submitted' } # def broadcast_notification diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb index 1fb438b42..edb011739 100644 --- a/app/services/notification_service.rb +++ b/app/services/notification_service.rb @@ -33,6 +33,8 @@ class NotificationService attribut when 'champs' attribut + when 'submitted' + "Le dossier n°#{@dossier_id} a été déposé." else 'Notification par défaut' end diff --git a/spec/controllers/users/recapitulatif_controller_spec.rb b/spec/controllers/users/recapitulatif_controller_spec.rb index 31e12dad0..3cbbe1696 100644 --- a/spec/controllers/users/recapitulatif_controller_spec.rb +++ b/spec/controllers/users/recapitulatif_controller_spec.rb @@ -82,6 +82,10 @@ describe Users::RecapitulatifController, type: :controller do dossier.validated! post :submit, params: {dossier_id: dossier.id} end + + it 'Internal notification is created' do + expect(Notification.where(dossier_id: dossier.id, type_notif: 'submitted').first).not_to be_nil + end end end end From a727c5146f707362b06346a70a68bc6f7b3d56fd Mon Sep 17 00:00:00 2001 From: JC Date: Mon, 26 Dec 2016 14:16:08 +0100 Subject: [PATCH 12/30] Cannot have the right feature test about invites, both side User and Gestionnaire --- app/views/dossiers/_invites.html.haml | 6 ++--- ...ckoffice_dossierscontroller_show.html.haml | 9 +++---- ...ers_recapitulatifcontroller_show.html.haml | 8 +++--- spec/features/backoffice/invitation_spec.rb | 25 +++++++++++++++++++ spec/features/users/invitation_spec.rb | 24 ++++++++++++++++++ 5 files changed, 60 insertions(+), 12 deletions(-) create mode 100644 spec/features/backoffice/invitation_spec.rb create mode 100644 spec/features/users/invitation_spec.rb diff --git a/app/views/dossiers/_invites.html.haml b/app/views/dossiers/_invites.html.haml index 2474ad7f5..72307147e 100644 --- a/app/views/dossiers/_invites.html.haml +++ b/app/views/dossiers/_invites.html.haml @@ -12,7 +12,7 @@ Aucune personne invitée .col-md-3.col-sm-3.col-xs-3.col-lg-3 - =form_tag invites_dossier_path(dossier_id: @facade.dossier.id), method: :post, class: 'form-inline' do - =text_field_tag :email, '', class: 'form-control', placeholder: 'Envoyer une invitation' - =submit_tag 'Ajouter', class: 'btn btn-success' + = form_tag invites_dossier_path(dossier_id: @facade.dossier.id), method: :post, class: 'form-inline' do + = text_field_tag :email, '', class: 'form-control', placeholder: 'Envoyer une invitation' + = submit_tag 'Ajouter', class: 'btn btn-success', id: 'send-invitation' diff --git a/app/views/layouts/navbars/_navbar_backoffice_dossierscontroller_show.html.haml b/app/views/layouts/navbars/_navbar_backoffice_dossierscontroller_show.html.haml index 37d5c5a22..744d4e583 100644 --- a/app/views/layouts/navbars/_navbar_backoffice_dossierscontroller_show.html.haml +++ b/app/views/layouts/navbars/_navbar_backoffice_dossierscontroller_show.html.haml @@ -14,7 +14,7 @@ Suivre le dossier %div.row %div.col-lg-12.col-md-12.col-sm-12.col-xs-12 - %div.dropdown-toggle{ 'data-toggle' => 'dropdown', 'aria-haspopup' => true, 'aria-expanded' => false } + %div#invitations.dropdown-toggle{ 'data-toggle' => 'dropdown', 'aria-haspopup' => true, 'aria-expanded' => false } %i.fa.fa-user = t('utils.involved') %div.dropdown-menu.dropdown-menu-right.dropdown-pannel @@ -34,7 +34,6 @@ = t('dynamics.dossiers.invites.empty') %li - =form_tag invites_dossier_path(dossier_id: @facade.dossier.id), method: :post, class: 'form-inline' do - =text_field_tag :email, '', class: 'form-control', placeholder: 'Envoyer une invitation' - =submit_tag 'Ajouter', class: 'btn btn-success' - + = form_tag invites_dossier_path(dossier_id: @facade.dossier.id), method: :post, class: 'form-inline', id: 'send-invitation' do + = text_field_tag :email, '', class: 'form-control', placeholder: 'Envoyer une invitation', id: 'invitation-email' + = submit_tag 'Ajouter', class: 'btn btn-success' diff --git a/app/views/layouts/navbars/_navbar_users_recapitulatifcontroller_show.html.haml b/app/views/layouts/navbars/_navbar_users_recapitulatifcontroller_show.html.haml index 18dfdf885..ba834c09f 100644 --- a/app/views/layouts/navbars/_navbar_users_recapitulatifcontroller_show.html.haml +++ b/app/views/layouts/navbars/_navbar_users_recapitulatifcontroller_show.html.haml @@ -4,7 +4,7 @@ %div.col-lg-3.col-md-3.col-sm-3.col-xs-3.options %div.row.centered-option %div.col-lg-12.col-md-12.col-sm-12.col-xs-12 - %div.dropdown-toggle{ 'data-toggle' => 'dropdown', 'aria-haspopup' => true, 'aria-expanded' => false } + %div#invitations.dropdown-toggle{ 'data-toggle' => 'dropdown', 'aria-haspopup' => true, 'aria-expanded' => false } %i.fa.fa-user = t('utils.involved') %div.dropdown-menu.dropdown-menu-right.dropdown-pannel @@ -24,6 +24,6 @@ = t('dynamics.dossiers.invites.empty') %li - =form_tag invites_dossier_path(dossier_id: @facade.dossier.id), method: :post, class: 'form-inline' do - =text_field_tag :email, '', class: 'form-control', placeholder: 'Envoyer une invitation' - =submit_tag 'Ajouter', class: 'btn btn-success' + = form_tag invites_dossier_path(dossier_id: @facade.dossier.id), method: :post, class: 'form-inline', id: 'send-invitation' do + = text_field_tag :email, '', class: 'form-control', placeholder: 'Envoyer une invitation', id: 'invitation-email' + = submit_tag 'Ajouter', class: 'btn btn-success' diff --git a/spec/features/backoffice/invitation_spec.rb b/spec/features/backoffice/invitation_spec.rb new file mode 100644 index 000000000..ffeb61158 --- /dev/null +++ b/spec/features/backoffice/invitation_spec.rb @@ -0,0 +1,25 @@ +require 'spec_helper' + +feature 'As an Accompagnateur I can send invitations from dossiers', js: true do + + let(:user) { create(:user) } + let(:gestionnaire) { create(:gestionnaire) } + let(:procedure_1) { create(:procedure, :with_type_de_champ, libelle: 'procedure 1') } + + before 'Assign procedures to Accompagnateur and generating dossiers for each' do + create :assign_to, gestionnaire: gestionnaire, procedure: procedure_1 + Dossier.create(procedure_id: procedure_1.id.to_s, user: user, state: 'initiated') + login_as gestionnaire, scope: :gestionnaire + visit backoffice_dossier_path(1) + end + + context 'On dossier show' do + + scenario 'Sending invitation' do + page.find('#invitations').click + page.find('#invitation-email').set('toto@email.com') + page.find('#send-invitation .btn-success').trigger('click') + end + + end +end diff --git a/spec/features/users/invitation_spec.rb b/spec/features/users/invitation_spec.rb new file mode 100644 index 000000000..7611e6b07 --- /dev/null +++ b/spec/features/users/invitation_spec.rb @@ -0,0 +1,24 @@ +require 'spec_helper' + +feature 'As a User I can send invitations from dossiers', js: true do + + let(:user) { create(:user) } + let(:procedure_1) { create(:procedure, :with_type_de_champ, libelle: 'procedure 1') } + + before 'Assign procedures to Accompagnateur and generating dossiers for each' do + Dossier.create(procedure_id: procedure_1.id.to_s, user: user, state: 'initiated') + login_as user, scope: :user + visit users_dossier_recapitulatif_path(1) + end + + context 'On dossier show' do + + scenario 'Sending invitation' do + page.find('#invitations').click + fill_in 'invitation-email', with: 'toto@email.com' + page.find('#send-invitation .btn-success').trigger('click') + save_and_open_page + end + + end +end From 9a0a391c40ee903ffcb4f94b2dadc471985be978 Mon Sep 17 00:00:00 2001 From: Xavier J Date: Mon, 26 Dec 2016 14:38:00 +0100 Subject: [PATCH 13/30] Exclude notification for dossier state draft and for accompagnateur comments --- app/models/cerfa.rb | 4 +++- app/models/champ.rb | 4 +++- app/models/commentaire.rb | 4 +++- app/models/piece_justificative.rb | 4 +++- .../backoffice/commentaires_controller_spec.rb | 8 ++++++++ spec/factories/gestionnaire.rb | 2 +- 6 files changed, 21 insertions(+), 5 deletions(-) diff --git a/app/models/cerfa.rb b/app/models/cerfa.rb index 184060706..0e69ca60e 100644 --- a/app/models/cerfa.rb +++ b/app/models/cerfa.rb @@ -24,6 +24,8 @@ class Cerfa < ActiveRecord::Base private def internal_notification - NotificationService.new('cerfa', self.dossier.id).notify + unless dossier.state == 'draft' + NotificationService.new('cerfa', self.dossier.id).notify + end end end \ No newline at end of file diff --git a/app/models/champ.rb b/app/models/champ.rb index 0016b1c45..c9b956a85 100644 --- a/app/models/champ.rb +++ b/app/models/champ.rb @@ -52,6 +52,8 @@ class Champ < ActiveRecord::Base private def internal_notification - NotificationService.new('champs', self.dossier.id, self.libelle).notify + unless dossier.state == 'draft' + NotificationService.new('champs', self.dossier.id, self.libelle).notify + end end end diff --git a/app/models/commentaire.rb b/app/models/commentaire.rb index 2a785da37..c7645ce52 100644 --- a/app/models/commentaire.rb +++ b/app/models/commentaire.rb @@ -13,6 +13,8 @@ class Commentaire < ActiveRecord::Base private def internal_notification - NotificationService.new('commentaire', self.dossier.id).notify + if email == dossier.user.email || dossier.invites.pluck(:email).to_a.include?(email) + NotificationService.new('commentaire', self.dossier.id).notify + end end end diff --git a/app/models/piece_justificative.rb b/app/models/piece_justificative.rb index 405871a38..865120e18 100644 --- a/app/models/piece_justificative.rb +++ b/app/models/piece_justificative.rb @@ -49,6 +49,8 @@ class PieceJustificative < ActiveRecord::Base private def internal_notification - NotificationService.new('piece_justificative', self.dossier.id, self.libelle).notify + unless self.type_de_piece_justificative.nil? && dossier.state == 'draft' + NotificationService.new('piece_justificative', self.dossier.id, self.libelle).notify + end end end diff --git a/spec/controllers/backoffice/commentaires_controller_spec.rb b/spec/controllers/backoffice/commentaires_controller_spec.rb index 63ebb3261..2fccafe5e 100644 --- a/spec/controllers/backoffice/commentaires_controller_spec.rb +++ b/spec/controllers/backoffice/commentaires_controller_spec.rb @@ -36,6 +36,10 @@ describe Backoffice::CommentairesController, type: :controller do expect { subject }.to change(Follow, :count).by(0) end end + + it 'Internal notification is not create' do + expect { subject }.to change(Notification, :count).by (0) + end end context 'when document is upload whith a commentaire', vcr: {cassette_name: 'controllers_backoffice_commentaires_controller_doc_upload_with_comment'} do @@ -54,6 +58,10 @@ describe Backoffice::CommentairesController, type: :controller do subject end + it 'Internal notification is not create' do + expect { subject }.to change(Notification, :count).by (0) + end + describe 'piece justificative created' do let(:pj) { PieceJustificative.last } diff --git a/spec/factories/gestionnaire.rb b/spec/factories/gestionnaire.rb index dcdb76c62..63004f8e9 100644 --- a/spec/factories/gestionnaire.rb +++ b/spec/factories/gestionnaire.rb @@ -1,5 +1,5 @@ FactoryGirl.define do - sequence(:gestionnaire_email) { |n| "plop#{n}@plop.com" } + sequence(:gestionnaire_email) { |n| "gest#{n}@plop.com" } factory :gestionnaire do email { generate(:gestionnaire_email) } password 'password' From 48451553b9dcaf2f506d4de4967c596b01d97745 Mon Sep 17 00:00:00 2001 From: Xavier J Date: Mon, 26 Dec 2016 14:45:42 +0100 Subject: [PATCH 14/30] Change invites autorisation in commentaire model --- app/models/commentaire.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/commentaire.rb b/app/models/commentaire.rb index c7645ce52..09c147dd4 100644 --- a/app/models/commentaire.rb +++ b/app/models/commentaire.rb @@ -13,7 +13,7 @@ class Commentaire < ActiveRecord::Base private def internal_notification - if email == dossier.user.email || dossier.invites.pluck(:email).to_a.include?(email) + if email == dossier.user.email || dossier.invites_user.pluck(:email).to_a.include?(email) NotificationService.new('commentaire', self.dossier.id).notify end end From 42915979daaee157c610fc1e5153fb197208c62d Mon Sep 17 00:00:00 2001 From: JC Date: Mon, 26 Dec 2016 17:18:45 +0100 Subject: [PATCH 15/30] Notifications are shown in backoffice dossier show, limit 5 --- app/assets/stylesheets/left_pannel.scss | 28 +++++++++++++------ app/services/notification_service.rb | 2 +- app/services/sync_credentials_service.rb | 2 +- ...ckoffice_dossierscontroller_show.html.haml | 10 +++++-- 4 files changed, 28 insertions(+), 14 deletions(-) diff --git a/app/assets/stylesheets/left_pannel.scss b/app/assets/stylesheets/left_pannel.scss index 7debdf58c..0ba2276ff 100644 --- a/app/assets/stylesheets/left_pannel.scss +++ b/app/assets/stylesheets/left_pannel.scss @@ -64,17 +64,27 @@ width: 200px; margin-top: 20px; } - .tips { - margin: 0 10px 0 5px; + .notifications { + margin: 20px 10px 0 5px; .fa { - color: #FFFFFF; - font-size: 40px; - width: inherit; - padding: 5px; + font-size: 25px; + width: 100%; + margin: 0 0 15px 0; } - .notice { - font-size: 18px; - display: initial; + .notification { + margin: 10px 0 10px 0; + .type { + margin-bottom: 20px; + } + .updated-at { + color: #CCCCCC; + font-size: 12px; + text-align: left; + } + .split-hr { + width: 40px; + margin: auto; + } } } } diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb index edb011739..01bfe97e3 100644 --- a/app/services/notification_service.rb +++ b/app/services/notification_service.rb @@ -39,4 +39,4 @@ class NotificationService 'Notification par défaut' end end -end \ No newline at end of file +end diff --git a/app/services/sync_credentials_service.rb b/app/services/sync_credentials_service.rb index 690323759..491ec1d55 100644 --- a/app/services/sync_credentials_service.rb +++ b/app/services/sync_credentials_service.rb @@ -35,4 +35,4 @@ class SyncCredentialsService end end end -end \ No newline at end of file +end diff --git a/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_show.html.haml b/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_show.html.haml index a47e64175..6d3e227b1 100644 --- a/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_show.html.haml +++ b/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_show.html.haml @@ -30,6 +30,10 @@ %div.split-hr-left %div.dossier-state= @facade.dossier.display_state %div.split-hr-left - %div.tips.hidden - %i.fa.fa-lightbulb-o - %div.notice= "Ceci est un bloc destiné à contenir des informations sur ce que vous êtes censé pouvoir faire à ce stade de traitement du dossier." + %div.notifications + %i.fa.fa-bell-o + - @facade.dossier.notifications.limit(5).each do |notification| + .notification + .updated-at= notification.updated_at.strftime('%d/%m/%Y %H:%M') + .type= notification.liste.last + .split-hr From 02ce392ff350fbbb13bc8c7a2fff0d220e003883 Mon Sep 17 00:00:00 2001 From: JC Date: Mon, 26 Dec 2016 17:24:40 +0100 Subject: [PATCH 16/30] No notifications result in displayed message --- ...l_backoffice_dossierscontroller_show.html.haml | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_show.html.haml b/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_show.html.haml index 6d3e227b1..6e101ba59 100644 --- a/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_show.html.haml +++ b/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_show.html.haml @@ -31,9 +31,12 @@ %div.dossier-state= @facade.dossier.display_state %div.split-hr-left %div.notifications - %i.fa.fa-bell-o - - @facade.dossier.notifications.limit(5).each do |notification| - .notification - .updated-at= notification.updated_at.strftime('%d/%m/%Y %H:%M') - .type= notification.liste.last - .split-hr + - if @facade.dossier.notifications.empty? + = "Aucune notification pour le moment." + - else + %i.fa.fa-bell-o + - @facade.dossier.notifications.limit(5).each do |notification| + .notification + .updated-at= notification.updated_at.strftime('%d/%m/%Y %H:%M') + .type= notification.liste.last + .split-hr From 153c472ef64eb8081346ab70bb8259387b800988 Mon Sep 17 00:00:00 2001 From: Xavier J Date: Mon, 26 Dec 2016 17:25:59 +0100 Subject: [PATCH 17/30] Add notifications into procedure list on back office report --- app/facades/dossiers_list_facades.rb | 2 +- app/models/gestionnaire.rb | 12 +++++++ ...koffice_dossierscontroller_index.html.haml | 3 ++ spec/facades/dossiers_list_facades_spec.rb | 4 ++- spec/models/gestionnaire_spec.rb | 36 +++++++++++++++++++ 5 files changed, 55 insertions(+), 2 deletions(-) diff --git a/app/facades/dossiers_list_facades.rb b/app/facades/dossiers_list_facades.rb index bed18c852..62e235748 100644 --- a/app/facades/dossiers_list_facades.rb +++ b/app/facades/dossiers_list_facades.rb @@ -27,7 +27,7 @@ class DossiersListFacades end def gestionnaire_procedures_name_and_id_list - @current_devise_profil.procedures.order('libelle ASC').inject([]) { |acc, procedure| acc.push({id: procedure.id, libelle: procedure.libelle}) } + @current_devise_profil.procedures.order('libelle ASC').inject([]) { |acc, procedure| acc.push({id: procedure.id, libelle: procedure.libelle, notification_unread: @current_devise_profil.notification_unread(procedure)}) } end def procedure_id diff --git a/app/models/gestionnaire.rb b/app/models/gestionnaire.rb index d98b2e742..0a89eee03 100644 --- a/app/models/gestionnaire.rb +++ b/app/models/gestionnaire.rb @@ -63,6 +63,18 @@ class Gestionnaire < ActiveRecord::Base PreferenceSmartListingPage.create(page: 1, procedure: nil, gestionnaire: self, liste: 'a_traiter') end + def notification_unread procedure + procedure_ids = dossiers_follow.pluck(:procedure_id) + + if procedure_ids.include?(procedure.id) + return dossiers_follow.where(procedure_id: procedure.id) + .inject(0) do |acc, dossier| + acc += dossier.notifications.where(already_read: false).count + end + end + 0 + end + private def valid_couple_table_attr? table, column diff --git a/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_index.html.haml b/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_index.html.haml index 037f35a33..bee85d9c5 100644 --- a/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_index.html.haml +++ b/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_index.html.haml @@ -17,3 +17,6 @@ = link_to backoffice_dossiers_procedure_path(procedure[:id]), {title: procedure[:libelle]} do %div.procedure_list_element{ class: ('active' if procedure[:id] == @facade_data_view.procedure.id rescue '') } = truncate(procedure[:libelle], length: 50) + -if procedure[:notification_unread] > 0 + .badge.progress-bar-warning + = procedure[:notification_unread] diff --git a/spec/facades/dossiers_list_facades_spec.rb b/spec/facades/dossiers_list_facades_spec.rb index 7dcd9a6e0..cc8eeb4be 100644 --- a/spec/facades/dossiers_list_facades_spec.rb +++ b/spec/facades/dossiers_list_facades_spec.rb @@ -50,10 +50,12 @@ describe DossiersListFacades do it { expect(subject.first[:id]).to eq procedure.id } it { expect(subject.first[:libelle]).to eq procedure.libelle } + it { expect(subject.first[:notification_unread]).to eq 0 } + it { expect(subject.last[:id]).to eq procedure_2.id } it { expect(subject.last[:libelle]).to eq procedure_2.libelle } - + it { expect(subject.last[:notification_unread]).to eq 0 } end describe '#active_filter?' do diff --git a/spec/models/gestionnaire_spec.rb b/spec/models/gestionnaire_spec.rb index 18fc65d6d..572240d48 100644 --- a/spec/models/gestionnaire_spec.rb +++ b/spec/models/gestionnaire_spec.rb @@ -208,4 +208,40 @@ describe Gestionnaire, type: :model do expect(admin.valid_password?('super secret')).to be(true) end end + + describe '#notification_unread' do + subject { gestionnaire.notification_unread procedure } + + context 'when gestionnaire follow any dossier' do + it { is_expected.to eq 0 } + it { expect(gestionnaire.follows.count).to eq 0 } + it { expect_any_instance_of(Dossier::ActiveRecord_AssociationRelation).not_to receive(:inject) + subject } + end + + context 'when gestionnaire follow any dossier into the procedure past in params' do + before do + create :follow, gestionnaire: gestionnaire, dossier: create(:dossier, procedure: procedure_2) + end + + it { is_expected.to eq 0 } + it { expect(gestionnaire.follows.count).to eq 1 } + it { expect_any_instance_of(Dossier::ActiveRecord_AssociationRelation).not_to receive(:inject) + subject } + end + + context 'when gestionnaire follow a dossier with a notification into the procedure past in params' do + let(:dossier) { create(:dossier, procedure: procedure, state: 'initiated') } + + before do + create :follow, gestionnaire: gestionnaire, dossier: dossier + create :notification, dossier: dossier + end + + it { is_expected.to eq 1 } + it { expect(gestionnaire.follows.count).to eq 1 } + it { expect_any_instance_of(Dossier::ActiveRecord_AssociationRelation).to receive(:inject) + subject } + end + end end From 45d5177d521ac533b20e9fd0bd55526134775059 Mon Sep 17 00:00:00 2001 From: JC Date: Mon, 26 Dec 2016 17:36:02 +0100 Subject: [PATCH 18/30] Prepend notification message for champs and piece_justificative --- ...eft_panel_backoffice_dossierscontroller_show.html.haml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_show.html.haml b/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_show.html.haml index 6e101ba59..f8164b27a 100644 --- a/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_show.html.haml +++ b/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_show.html.haml @@ -38,5 +38,11 @@ - @facade.dossier.notifications.limit(5).each do |notification| .notification .updated-at= notification.updated_at.strftime('%d/%m/%Y %H:%M') - .type= notification.liste.last + - if ['champs', 'piece_justificative'].include?(notification.type_notif) + - if notification.liste.size > 1 + .type= "Plusieurs attributs ont été changés, dont: #{notification.liste.last}" + - else + .type= "Un attribut à été changé: #{notification.liste.last}" + - else + .type= notification.liste.last .split-hr From f0d0bfc4279c5f0cb7d70fb528b1298a55bdfd14 Mon Sep 17 00:00:00 2001 From: JC Date: Mon, 26 Dec 2016 17:55:31 +0100 Subject: [PATCH 19/30] Listing updated champs, saving only champs changed --- app/services/champs_service.rb | 4 ++-- .../_left_panel_backoffice_dossierscontroller_show.html.haml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/services/champs_service.rb b/app/services/champs_service.rb index faf25cf7c..04fdf9602 100644 --- a/app/services/champs_service.rb +++ b/app/services/champs_service.rb @@ -19,9 +19,9 @@ class ChampsService end end - champ.save + champ.save if champ.changed? end errors end -end \ No newline at end of file +end diff --git a/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_show.html.haml b/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_show.html.haml index f8164b27a..b424cc9d6 100644 --- a/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_show.html.haml +++ b/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_show.html.haml @@ -40,7 +40,7 @@ .updated-at= notification.updated_at.strftime('%d/%m/%Y %H:%M') - if ['champs', 'piece_justificative'].include?(notification.type_notif) - if notification.liste.size > 1 - .type= "Plusieurs attributs ont été changés, dont: #{notification.liste.last}" + .type= "Plusieurs attributs ont été changés, dont: #{notification.liste.join(" ")}" - else .type= "Un attribut à été changé: #{notification.liste.last}" - else From 97881182299d50f2bf92c9cf22086e05876ef1ff Mon Sep 17 00:00:00 2001 From: JC Date: Mon, 26 Dec 2016 17:59:08 +0100 Subject: [PATCH 20/30] Adapt listing for notifications, according champ or pieces --- ...left_panel_backoffice_dossierscontroller_show.html.haml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_show.html.haml b/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_show.html.haml index b424cc9d6..e3c496845 100644 --- a/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_show.html.haml +++ b/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_show.html.haml @@ -38,11 +38,16 @@ - @facade.dossier.notifications.limit(5).each do |notification| .notification .updated-at= notification.updated_at.strftime('%d/%m/%Y %H:%M') - - if ['champs', 'piece_justificative'].include?(notification.type_notif) + - if ['champs'].include?(notification.type_notif) - if notification.liste.size > 1 .type= "Plusieurs attributs ont été changés, dont: #{notification.liste.join(" ")}" - else .type= "Un attribut à été changé: #{notification.liste.last}" + - elsif ['piece_justificative'].include?(notification.type_notif) + - if notification.liste.size > 1 + .type= "Plusieurs pièces justificatives ont été changés, dont: #{notification.liste.join(" ")}" + - else + .type= "Une pièce justificative à été changée: #{notification.liste.last}" - else .type= notification.liste.last .split-hr From 4e6adf5bc35604d25de50bc56032ca58ab97a8af Mon Sep 17 00:00:00 2001 From: Xavier J Date: Mon, 26 Dec 2016 18:37:27 +0100 Subject: [PATCH 21/30] Fix some tests --- app/models/cerfa.rb | 2 +- app/models/champ.rb | 2 +- app/models/piece_justificative.rb | 2 +- spec/factories/commentaire.rb | 6 ++++++ spec/factories/notification.rb | 2 +- 5 files changed, 10 insertions(+), 4 deletions(-) diff --git a/app/models/cerfa.rb b/app/models/cerfa.rb index 0e69ca60e..6d6d0c702 100644 --- a/app/models/cerfa.rb +++ b/app/models/cerfa.rb @@ -5,7 +5,7 @@ class Cerfa < ActiveRecord::Base mount_uploader :content, CerfaUploader validates :content, :file_size => {:maximum => 20.megabytes} - after_save :internal_notification + after_save :internal_notification, if: Proc.new { !dossier.nil? } def empty? content.blank? diff --git a/app/models/champ.rb b/app/models/champ.rb index c9b956a85..e4a6e820e 100644 --- a/app/models/champ.rb +++ b/app/models/champ.rb @@ -5,7 +5,7 @@ class Champ < ActiveRecord::Base delegate :libelle, :type_champ, :order_place, :mandatory, :description, :drop_down_list, to: :type_de_champ - after_save :internal_notification + after_save :internal_notification, if: Proc.new { !dossier.nil? } def mandatory? mandatory diff --git a/app/models/piece_justificative.rb b/app/models/piece_justificative.rb index 865120e18..0c2056b6a 100644 --- a/app/models/piece_justificative.rb +++ b/app/models/piece_justificative.rb @@ -13,7 +13,7 @@ class PieceJustificative < ActiveRecord::Base validates :content, :file_size => {:maximum => 20.megabytes} validates :content, presence: true, allow_blank: false, allow_nil: false - after_save :internal_notification + after_save :internal_notification, if: Proc.new { !dossier.nil? } def empty? content.blank? diff --git a/spec/factories/commentaire.rb b/spec/factories/commentaire.rb index 791e295db..bb0a148ca 100644 --- a/spec/factories/commentaire.rb +++ b/spec/factories/commentaire.rb @@ -1,5 +1,11 @@ FactoryGirl.define do factory :commentaire do body 'plop' + + before(:create) do |commentaire, _evaluator| + unless commentaire.dossier + commentaire.dossier = create :dossier + end + end end end diff --git a/spec/factories/notification.rb b/spec/factories/notification.rb index 8192f381b..fe4d8ecd8 100644 --- a/spec/factories/notification.rb +++ b/spec/factories/notification.rb @@ -3,7 +3,7 @@ FactoryGirl.define do type_notif 'commentaire' liste [] - after(:create) do |notification, _evaluator| + before(:create) do |notification, _evaluator| unless notification.dossier notification.dossier = create :dossier end From ce5bf8d622a022a51f8957badcb651767e65ff86 Mon Sep 17 00:00:00 2001 From: Xavier J Date: Tue, 27 Dec 2016 10:47:23 +0100 Subject: [PATCH 22/30] =?UTF-8?q?Initialize=20fonction=20=C2=AB=C2=A0unrea?= =?UTF-8?q?d=5Fnotifications=C2=A0=C2=BB=20in=20DossierListFacade?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/facades/dossiers_list_facades.rb | 6 +++++- app/models/gestionnaire.rb | 2 +- ...ft_panel_backoffice_dossierscontroller_index.html.haml | 4 ++-- spec/facades/dossiers_list_facades_spec.rb | 8 ++++++-- spec/models/gestionnaire_spec.rb | 4 ++-- 5 files changed, 16 insertions(+), 8 deletions(-) diff --git a/app/facades/dossiers_list_facades.rb b/app/facades/dossiers_list_facades.rb index 62e235748..7fd490661 100644 --- a/app/facades/dossiers_list_facades.rb +++ b/app/facades/dossiers_list_facades.rb @@ -27,7 +27,11 @@ class DossiersListFacades end def gestionnaire_procedures_name_and_id_list - @current_devise_profil.procedures.order('libelle ASC').inject([]) { |acc, procedure| acc.push({id: procedure.id, libelle: procedure.libelle, notification_unread: @current_devise_profil.notification_unread(procedure)}) } + @current_devise_profil.procedures.order('libelle ASC').inject([]) { |acc, procedure| acc.push({id: procedure.id, libelle: procedure.libelle, unread_notifications: @current_devise_profil.unread_notifications(procedure)}) } + end + + def unread_notifications + Notification.all end def procedure_id diff --git a/app/models/gestionnaire.rb b/app/models/gestionnaire.rb index 0a89eee03..8a840f5db 100644 --- a/app/models/gestionnaire.rb +++ b/app/models/gestionnaire.rb @@ -63,7 +63,7 @@ class Gestionnaire < ActiveRecord::Base PreferenceSmartListingPage.create(page: 1, procedure: nil, gestionnaire: self, liste: 'a_traiter') end - def notification_unread procedure + def unread_notifications procedure procedure_ids = dossiers_follow.pluck(:procedure_id) if procedure_ids.include?(procedure.id) diff --git a/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_index.html.haml b/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_index.html.haml index bee85d9c5..141d14e0b 100644 --- a/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_index.html.haml +++ b/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_index.html.haml @@ -17,6 +17,6 @@ = link_to backoffice_dossiers_procedure_path(procedure[:id]), {title: procedure[:libelle]} do %div.procedure_list_element{ class: ('active' if procedure[:id] == @facade_data_view.procedure.id rescue '') } = truncate(procedure[:libelle], length: 50) - -if procedure[:notification_unread] > 0 + -if procedure[:unread_notifications] > 0 .badge.progress-bar-warning - = procedure[:notification_unread] + = procedure[:unread_notifications] diff --git a/spec/facades/dossiers_list_facades_spec.rb b/spec/facades/dossiers_list_facades_spec.rb index cc8eeb4be..c0c618d7e 100644 --- a/spec/facades/dossiers_list_facades_spec.rb +++ b/spec/facades/dossiers_list_facades_spec.rb @@ -50,12 +50,12 @@ describe DossiersListFacades do it { expect(subject.first[:id]).to eq procedure.id } it { expect(subject.first[:libelle]).to eq procedure.libelle } - it { expect(subject.first[:notification_unread]).to eq 0 } + it { expect(subject.first[:unread_notifications]).to eq 0 } it { expect(subject.last[:id]).to eq procedure_2.id } it { expect(subject.last[:libelle]).to eq procedure_2.libelle } - it { expect(subject.last[:notification_unread]).to eq 0 } + it { expect(subject.last[:unread_notifications]).to eq 0 } end describe '#active_filter?' do @@ -133,4 +133,8 @@ describe DossiersListFacades do end end end + + describe 'unread_notifications' do + pending + end end \ No newline at end of file diff --git a/spec/models/gestionnaire_spec.rb b/spec/models/gestionnaire_spec.rb index 572240d48..d16d4df2e 100644 --- a/spec/models/gestionnaire_spec.rb +++ b/spec/models/gestionnaire_spec.rb @@ -209,8 +209,8 @@ describe Gestionnaire, type: :model do end end - describe '#notification_unread' do - subject { gestionnaire.notification_unread procedure } + describe '#unread_notifications' do + subject { gestionnaire.unread_notifications procedure } context 'when gestionnaire follow any dossier' do it { is_expected.to eq 0 } From 2e13cb68184507b446422b627c62eedd907c6cfb Mon Sep 17 00:00:00 2001 From: Xavier J Date: Tue, 27 Dec 2016 10:57:21 +0100 Subject: [PATCH 23/30] Get gestionnaire unread notifications for his follows files --- app/facades/dossiers_list_facades.rb | 4 ++-- app/models/gestionnaire.rb | 6 +++++- spec/facades/dossiers_list_facades_spec.rb | 4 ---- spec/models/gestionnaire_spec.rb | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app/facades/dossiers_list_facades.rb b/app/facades/dossiers_list_facades.rb index 7fd490661..42477c69e 100644 --- a/app/facades/dossiers_list_facades.rb +++ b/app/facades/dossiers_list_facades.rb @@ -27,11 +27,11 @@ class DossiersListFacades end def gestionnaire_procedures_name_and_id_list - @current_devise_profil.procedures.order('libelle ASC').inject([]) { |acc, procedure| acc.push({id: procedure.id, libelle: procedure.libelle, unread_notifications: @current_devise_profil.unread_notifications(procedure)}) } + @current_devise_profil.procedures.order('libelle ASC').inject([]) { |acc, procedure| acc.push({id: procedure.id, libelle: procedure.libelle, unread_notifications: @current_devise_profil.notifications_for(procedure)}) } end def unread_notifications - Notification.all + current_devise_profil.notifications end def procedure_id diff --git a/app/models/gestionnaire.rb b/app/models/gestionnaire.rb index 8a840f5db..10a6953af 100644 --- a/app/models/gestionnaire.rb +++ b/app/models/gestionnaire.rb @@ -63,7 +63,11 @@ class Gestionnaire < ActiveRecord::Base PreferenceSmartListingPage.create(page: 1, procedure: nil, gestionnaire: self, liste: 'a_traiter') end - def unread_notifications procedure + def notifications + Notification.where(already_read: false, dossier_id: follows.pluck(:dossier_id) ) + end + + def notifications_for procedure procedure_ids = dossiers_follow.pluck(:procedure_id) if procedure_ids.include?(procedure.id) diff --git a/spec/facades/dossiers_list_facades_spec.rb b/spec/facades/dossiers_list_facades_spec.rb index c0c618d7e..f10826990 100644 --- a/spec/facades/dossiers_list_facades_spec.rb +++ b/spec/facades/dossiers_list_facades_spec.rb @@ -133,8 +133,4 @@ describe DossiersListFacades do end end end - - describe 'unread_notifications' do - pending - end end \ No newline at end of file diff --git a/spec/models/gestionnaire_spec.rb b/spec/models/gestionnaire_spec.rb index d16d4df2e..e61990c7b 100644 --- a/spec/models/gestionnaire_spec.rb +++ b/spec/models/gestionnaire_spec.rb @@ -209,8 +209,8 @@ describe Gestionnaire, type: :model do end end - describe '#unread_notifications' do - subject { gestionnaire.unread_notifications procedure } + describe '#notifications_for' do + subject { gestionnaire.notifications_for procedure } context 'when gestionnaire follow any dossier' do it { is_expected.to eq 0 } From e37012dce67a7fc845795036c80a3ef2eb8c3f79 Mon Sep 17 00:00:00 2001 From: Xavier J Date: Tue, 27 Dec 2016 11:06:09 +0100 Subject: [PATCH 24/30] Add badge for new files in procedure list for gestionnaire --- app/facades/dossiers_list_facades.rb | 4 ++++ ...eft_panel_backoffice_dossierscontroller_index.html.haml | 7 ++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/app/facades/dossiers_list_facades.rb b/app/facades/dossiers_list_facades.rb index 42477c69e..b07b8652c 100644 --- a/app/facades/dossiers_list_facades.rb +++ b/app/facades/dossiers_list_facades.rb @@ -26,6 +26,10 @@ class DossiersListFacades current_devise_profil.dossiers.where(state: :initiated, archived: false).count end + def new_dossier_number procedure_id + current_devise_profil.dossiers.where(state: :initiated, archived: false, procedure_id: procedure_id).count + end + def gestionnaire_procedures_name_and_id_list @current_devise_profil.procedures.order('libelle ASC').inject([]) { |acc, procedure| acc.push({id: procedure.id, libelle: procedure.libelle, unread_notifications: @current_devise_profil.notifications_for(procedure)}) } end diff --git a/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_index.html.haml b/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_index.html.haml index 141d14e0b..2b42db2df 100644 --- a/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_index.html.haml +++ b/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_index.html.haml @@ -17,6 +17,11 @@ = link_to backoffice_dossiers_procedure_path(procedure[:id]), {title: procedure[:libelle]} do %div.procedure_list_element{ class: ('active' if procedure[:id] == @facade_data_view.procedure.id rescue '') } = truncate(procedure[:libelle], length: 50) + - total_new = @facade_data_view.new_dossier_number procedure[:id] + - if total_new > 0 + .badge.progress-bar-success{title:'Nouveaux dossiers'} + = total_new -if procedure[:unread_notifications] > 0 - .badge.progress-bar-warning + .badge.progress-bar-warning{title: 'Notifications'} = procedure[:unread_notifications] + From cea14845d244ae5e8d8826b486d42b91a48fea94 Mon Sep 17 00:00:00 2001 From: JC Date: Tue, 27 Dec 2016 11:15:20 +0100 Subject: [PATCH 25/30] Start backoffice dossier index menu, enable switch between procedures and notifications in left-pannel --- app/assets/stylesheets/dossiers.scss | 2 +- app/assets/stylesheets/left_pannel.scss | 37 ++++++++++++++++++- app/assets/stylesheets/search.scss | 2 +- ...koffice_dossierscontroller_index.html.haml | 5 +++ 4 files changed, 43 insertions(+), 3 deletions(-) diff --git a/app/assets/stylesheets/dossiers.scss b/app/assets/stylesheets/dossiers.scss index 61dcf0a52..f7793c753 100644 --- a/app/assets/stylesheets/dossiers.scss +++ b/app/assets/stylesheets/dossiers.scss @@ -67,5 +67,5 @@ h5 span { .split-hr-left { border-bottom: 1px solid #FFFFFF; - margin: 20px 10px 0px 0; + margin: 20px 10px 0px 10px; } diff --git a/app/assets/stylesheets/left_pannel.scss b/app/assets/stylesheets/left_pannel.scss index 0ba2276ff..8c113f4a2 100644 --- a/app/assets/stylesheets/left_pannel.scss +++ b/app/assets/stylesheets/left_pannel.scss @@ -1,6 +1,6 @@ #left-pannel { margin-top: 60px; - padding: 0 0 0 10px; + padding: 0; background-color: #003189; height: calc(100% - 60px); position: fixed; @@ -51,6 +51,41 @@ } } #menu-block { + #switch-buttons { + height: 40px; + line-height: 40px; + font-size: 16px; + margin-top: 20px; + margin-left: auto; + margin-right: auto; + width: 205px; + border: 1px solid; + padding: 0 0 0 10px; + border-radius: 25px; + #switch-procedures { + height: 38px; + margin: 0 -5px 0 -10px; + padding-left: 10px; + width: 100px; + display: inline-block; + background-color: #CCCCCC; + border-radius: 25px 0 0 25px; + } + #switch-notifications { + width: 100px; + background-color: #CCCCCC; + display: inline-block; + border-radius: 0 25px 25px 0; + height: 38px; + margin: 0 0 0 -5px; + padding: 0 0 0 5px; + } + } + .split-hr { + border-bottom: 1px solid #FFFFFF; + width: 200px; + margin: 20px 0 20px 0; + } } #infos-block { .split-hr { diff --git a/app/assets/stylesheets/search.scss b/app/assets/stylesheets/search.scss index 969d5b7a6..ce3219ac5 100644 --- a/app/assets/stylesheets/search.scss +++ b/app/assets/stylesheets/search.scss @@ -1,5 +1,5 @@ #search-block{ - margin: 15px 10px 0 0; + margin: 15px 10px 0 10px; height: 30px; } diff --git a/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_index.html.haml b/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_index.html.haml index 2b42db2df..cfdc87824 100644 --- a/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_index.html.haml +++ b/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_index.html.haml @@ -9,6 +9,11 @@ %div#action-block %div#menu-block + %div.split-hr-left + #switch-buttons + #switch-procedures Procédures + | + #switch-notifications Notifications %div#infos-block %div.split-hr-left From 4d765d3b469f1c10419d78d8ffbe319f530fcc4e Mon Sep 17 00:00:00 2001 From: Xavier J Date: Tue, 27 Dec 2016 11:23:19 +0100 Subject: [PATCH 26/30] Past all notification to read when gestionnaire is on back office dossier show --- .../backoffice/dossiers_controller.rb | 3 ++ app/views/backoffice/dossiers/_list.html.haml | 2 +- .../backoffice/dossiers_controller_spec.rb | 30 +++++++++++-------- 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/app/controllers/backoffice/dossiers_controller.rb b/app/controllers/backoffice/dossiers_controller.rb index 3537d6c5e..73fd4ec13 100644 --- a/app/controllers/backoffice/dossiers_controller.rb +++ b/app/controllers/backoffice/dossiers_controller.rb @@ -19,6 +19,7 @@ class Backoffice::DossiersController < Backoffice::DossiersListController def show create_dossier_facade params[:id] + unless @facade.nil? @champs_private = @facade.champs_private @@ -27,6 +28,8 @@ class Backoffice::DossiersController < Backoffice::DossiersListController acc end end + + Notification.where(dossier_id: params[:id].to_i).update_all already_read: true end def filter diff --git a/app/views/backoffice/dossiers/_list.html.haml b/app/views/backoffice/dossiers/_list.html.haml index f2b6da4cb..43e50eff7 100644 --- a/app/views/backoffice/dossiers/_list.html.haml +++ b/app/views/backoffice/dossiers/_list.html.haml @@ -21,7 +21,7 @@ %tr.dossier-row{id: "tr_dossier_#{dossier.id}", 'data-dossier_url' => backoffice_dossier_url(id: dossier.id)} - if smart_listing.name.to_s == 'follow_dossiers' %td.center - - total_notif = dossier.notifications.count + - total_notif = dossier.notifications.where(already_read: false).count - if total_notif == 0 .badge.progress-bar-default = total_notif diff --git a/spec/controllers/backoffice/dossiers_controller_spec.rb b/spec/controllers/backoffice/dossiers_controller_spec.rb index 34f2384b2..96e838d19 100644 --- a/spec/controllers/backoffice/dossiers_controller_spec.rb +++ b/spec/controllers/backoffice/dossiers_controller_spec.rb @@ -38,34 +38,40 @@ describe Backoffice::DossiersController, type: :controller do end describe 'GET #show' do + subject { get :show, params: {id: dossier_id} } + context 'gestionnaire is connected' do before do sign_in gestionnaire end it 'returns http success' do - get :show, params: {id: dossier_id} - expect(response).to have_http_status(200) + expect(subject).to have_http_status(200) + end + + describe 'all notifications unread are changed' do + it do + expect(Notification).to receive(:where).with(dossier_id: dossier_id).and_return(Notification::ActiveRecord_Relation) + expect(Notification::ActiveRecord_Relation).to receive(:update_all).with(already_read: true).and_return(true) + + subject + end end context ' when dossier is archived' do - before do - get :show, params: {id: dossier_archived.id} - end - it { expect(response).to redirect_to('/backoffice') } + let(:dossier_id) { dossier_archived } + + it { expect(subject).to redirect_to('/backoffice') } end context 'when dossier id does not exist' do - before do - get :show, params: {id: bad_dossier_id} - end - it { expect(response).to redirect_to('/backoffice') } + let(:dossier_id) { bad_dossier_id } + + it { expect(subject).to redirect_to('/backoffice') } end end context 'gestionnaire does not connected but dossier id is correct' do - subject { get :show, params: {id: dossier_id} } - it { is_expected.to redirect_to('/gestionnaires/sign_in') } end end From c01132c788f6db2a7eb95d7bd2bdf34891db3fc9 Mon Sep 17 00:00:00 2001 From: Xavier J Date: Tue, 27 Dec 2016 11:57:34 +0100 Subject: [PATCH 27/30] Delete old attr in database --- ...left_panel_backoffice_dossierscontroller_show.html.haml | 1 - ...left_panel_users_recapitulatifcontroller_show.html.haml | 1 - config/locales/models/dossier/fr.yml | 4 ---- db/migrate/20161227103823_delete_old_attr_in_data_base.rb | 7 +++++++ db/schema.rb | 5 +---- spec/models/dossier_spec.rb | 1 - 6 files changed, 8 insertions(+), 11 deletions(-) create mode 100644 db/migrate/20161227103823_delete_old_attr_in_data_base.rb diff --git a/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_show.html.haml b/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_show.html.haml index e3c496845..be7e47390 100644 --- a/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_show.html.haml +++ b/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_show.html.haml @@ -1,6 +1,5 @@ %div#first-block %div.infos - %div.projet-name #{@facade.dossier.nom_projet.capitalize rescue nil} #dossier_id= t('dynamics.dossiers.numéro') + @facade.dossier.id.to_s %div#action-block diff --git a/app/views/layouts/left_panels/_left_panel_users_recapitulatifcontroller_show.html.haml b/app/views/layouts/left_panels/_left_panel_users_recapitulatifcontroller_show.html.haml index bc0ebdb0f..23397d47d 100644 --- a/app/views/layouts/left_panels/_left_panel_users_recapitulatifcontroller_show.html.haml +++ b/app/views/layouts/left_panels/_left_panel_users_recapitulatifcontroller_show.html.haml @@ -2,7 +2,6 @@ %div.en-cours %h2 Récapitulatif %div.infos - %div #{@facade.dossier.nom_projet} %div= t('dynamics.dossiers.numéro') + @facade.dossier.id.to_s %div#action-block diff --git a/config/locales/models/dossier/fr.yml b/config/locales/models/dossier/fr.yml index 9663b2795..576c47885 100644 --- a/config/locales/models/dossier/fr.yml +++ b/config/locales/models/dossier/fr.yml @@ -26,10 +26,6 @@ fr: mail_contact: blank: 'doit être rempli' invalid: 'est incorrect' - nom_projet: - blank: 'doit être rempli' - description: - blank: 'doit être remplie' montant_projet: blank: 'doit être rempli' montant_aide_demande: diff --git a/db/migrate/20161227103823_delete_old_attr_in_data_base.rb b/db/migrate/20161227103823_delete_old_attr_in_data_base.rb new file mode 100644 index 000000000..92fa6a3e9 --- /dev/null +++ b/db/migrate/20161227103823_delete_old_attr_in_data_base.rb @@ -0,0 +1,7 @@ +class DeleteOldAttrInDataBase < ActiveRecord::Migration[5.0] + def change + remove_column :dossiers, :nom_projet + remove_column :procedures, :test + remove_column :notifications, :multiple + end +end diff --git a/db/schema.rb b/db/schema.rb index 924830524..e9491dca0 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: 20161221153929) do +ActiveRecord::Schema.define(version: 20161227103823) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -118,7 +118,6 @@ ActiveRecord::Schema.define(version: 20161221153929) do create_table "dossiers", force: :cascade do |t| t.boolean "autorisation_donnees" - t.string "nom_projet" t.integer "procedure_id" t.datetime "created_at" t.datetime "updated_at" @@ -252,7 +251,6 @@ ActiveRecord::Schema.define(version: 20161221153929) do create_table "notifications", force: :cascade do |t| t.boolean "already_read", default: false t.string "liste", array: true - t.boolean "multiple", default: false t.string "type_notif" t.datetime "created_at" t.datetime "updated_at" @@ -313,7 +311,6 @@ ActiveRecord::Schema.define(version: 20161221153929) do t.string "lien_demarche" t.datetime "created_at", null: false t.datetime "updated_at", null: false - t.boolean "test" t.integer "administrateur_id" t.boolean "archived", default: false t.boolean "euro_flag", default: false diff --git a/spec/models/dossier_spec.rb b/spec/models/dossier_spec.rb index 4349748ad..ddbf350ce 100644 --- a/spec/models/dossier_spec.rb +++ b/spec/models/dossier_spec.rb @@ -5,7 +5,6 @@ describe Dossier do describe 'database columns' do it { is_expected.to have_db_column(:autorisation_donnees) } - it { is_expected.to have_db_column(:nom_projet) } it { is_expected.to have_db_column(:created_at) } it { is_expected.to have_db_column(:updated_at) } it { is_expected.to have_db_column(:state) } From 7ee555a1209219bf02286364b7bfec47578a09b0 Mon Sep 17 00:00:00 2001 From: Xavier J Date: Tue, 27 Dec 2016 15:05:19 +0100 Subject: [PATCH 28/30] Disabled broadcasting --- app/assets/javascripts/channels/notifications.js | 2 +- app/models/notification.rb | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/channels/notifications.js b/app/assets/javascripts/channels/notifications.js index a766b8cbf..78248d290 100644 --- a/app/assets/javascripts/channels/notifications.js +++ b/app/assets/javascripts/channels/notifications.js @@ -1,8 +1,8 @@ App.messages = App.cable.subscriptions.create('NotificationsChannel', { received: function (data) { - if (window.location.href.indexOf('backoffice') !== -1) { $("#notification_alert").html(data['message']); + slideIn_notification_alert(); } } diff --git a/app/models/notification.rb b/app/models/notification.rb index be256f25a..4ff810f37 100644 --- a/app/models/notification.rb +++ b/app/models/notification.rb @@ -13,6 +13,7 @@ class Notification < ActiveRecord::Base # def broadcast_notification # ActionCable.server.broadcast 'notifications', - # message: "Nouveau commentaire posté sur le dossier #{self.dossier.id}" + # message: "Dossier n°#{self.dossier.id} : #{self.liste.last}", + # dossier: {id: self.dossier.id} # end end From fb737df463c983c71c8b4c3de461fee75d4b307a Mon Sep 17 00:00:00 2001 From: JC Date: Tue, 27 Dec 2016 15:26:41 +0100 Subject: [PATCH 29/30] Both index and show have notification on there left pannels --- app/assets/javascripts/dossiers.js | 17 +++++++ app/assets/javascripts/dossiers_list_link.js | 9 ++-- app/assets/stylesheets/dossiers.scss | 10 ++--- app/assets/stylesheets/left_pannel.scss | 44 +++++++++++++++---- app/decorators/notification_decorator.rb | 8 ++++ app/facades/dossier_facades.rb | 4 ++ app/facades/dossiers_list_facades.rb | 2 +- app/models/gestionnaire.rb | 2 +- ...koffice_dossierscontroller_index.html.haml | 11 +++-- ...ckoffice_dossierscontroller_show.html.haml | 2 +- 10 files changed, 83 insertions(+), 26 deletions(-) create mode 100644 app/decorators/notification_decorator.rb diff --git a/app/assets/javascripts/dossiers.js b/app/assets/javascripts/dossiers.js index adc57a499..c294b6c16 100644 --- a/app/assets/javascripts/dossiers.js +++ b/app/assets/javascripts/dossiers.js @@ -1,5 +1,22 @@ $(document).on('page:load', the_terms); $(document).ready(the_terms); +$(document).on('page:load', pannel_switch); +$(document).ready(pannel_switch); + +function pannel_switch() { + $('#switch-notifications').click(function () { + $('#procedure_list').addClass('hidden'); + $('#notifications_list').removeClass('hidden'); + $(this).addClass('active'); + $('#switch-procedures').removeClass('active'); + }) + $('#switch-procedures').click(function () { + $('#notifications_list').addClass('hidden'); + $('#procedure_list').removeClass('hidden'); + $(this).addClass('active'); + $('#switch-notifications').removeClass('active'); + }) +} function the_terms() { var the_terms = $("#dossier_autorisation_donnees"); diff --git a/app/assets/javascripts/dossiers_list_link.js b/app/assets/javascripts/dossiers_list_link.js index 1764dd571..09fb31542 100644 --- a/app/assets/javascripts/dossiers_list_link.js +++ b/app/assets/javascripts/dossiers_list_link.js @@ -1,9 +1,8 @@ $(document).on('page:load', link_init); $(document).ready(link_init); - function link_init() { - $('#dossiers_list tr').on('click', function () { - $(location).attr('href', $(this).data('dossier_url')) - }); -} \ No newline at end of file + $('#dossiers_list tr').on('click', function () { + $(location).attr('href', $(this).data('dossier_url')) + }); +} diff --git a/app/assets/stylesheets/dossiers.scss b/app/assets/stylesheets/dossiers.scss index f7793c753..31fe3e57b 100644 --- a/app/assets/stylesheets/dossiers.scss +++ b/app/assets/stylesheets/dossiers.scss @@ -42,24 +42,22 @@ h5 span { cursor: pointer; } -#procedure_list { +#procedure_list, #notifications_list { margin-left: -10px; margin-top: 20px; a, a:hover { color: #FFFFFF; text-decoration: none; } - - .procedure_list_element.active{ + .procedure_list_element.active, .notification.active { background-color: #668ABD; } - - .procedure_list_element { + .procedure_list_element, .notification { padding: 15px 40px 15px 20px; cursor: pointer; line-height: 1.8em; } - .procedure_list_element:hover{ + .procedure_list_element:hover, .notification:hover { background-color: #668ABD; cursor: pointer; } diff --git a/app/assets/stylesheets/left_pannel.scss b/app/assets/stylesheets/left_pannel.scss index 8c113f4a2..08aadf3a1 100644 --- a/app/assets/stylesheets/left_pannel.scss +++ b/app/assets/stylesheets/left_pannel.scss @@ -52,8 +52,8 @@ } #menu-block { #switch-buttons { - height: 40px; - line-height: 40px; + height: 30px; + line-height: 30px; font-size: 16px; margin-top: 20px; margin-left: auto; @@ -62,21 +62,33 @@ border: 1px solid; padding: 0 0 0 10px; border-radius: 25px; + cursor: pointer; + .active { + background-color: #668ABD !important; + cursor: default; + } + .separator { + height: 26px; + width: 1px; + display: inline-block; + background-color: #FFFFFF; + } + #switch-procedures:hover, #switch-notifications:hover { + background-color: #668AEA; + } #switch-procedures { - height: 38px; - margin: 0 -5px 0 -10px; + height: 28px; + margin: 0 0 0 -10px; padding-left: 10px; width: 100px; display: inline-block; - background-color: #CCCCCC; border-radius: 25px 0 0 25px; } #switch-notifications { - width: 100px; - background-color: #CCCCCC; + width: 103px; display: inline-block; border-radius: 0 25px 25px 0; - height: 38px; + height: 28px; margin: 0 0 0 -5px; padding: 0 0 0 5px; } @@ -98,6 +110,20 @@ font-size: 25px; width: 200px; margin-top: 20px; + width: 200px; + margin-left: auto; + margin-right: auto; + } + #notifications_list { + .notification { + padding: 10px 10px 10px 20px; + .dossier, .updated-at { + display: inline-block; + color: #CCCCCC; + font-size: 12px; + text-align: left; + } + } } .notifications { margin: 20px 10px 0 5px; @@ -107,7 +133,7 @@ margin: 0 0 15px 0; } .notification { - margin: 10px 0 10px 0; + margin: 10px 0 10px 10px; .type { margin-bottom: 20px; } diff --git a/app/decorators/notification_decorator.rb b/app/decorators/notification_decorator.rb new file mode 100644 index 000000000..911471e1a --- /dev/null +++ b/app/decorators/notification_decorator.rb @@ -0,0 +1,8 @@ +class NotificationDecorator < Draper::Decorator + delegate_all + + def index_display + ['champs', 'piece_justificative'].include?(type_notif) ? type = liste.join(" ") : type = liste.last + { dossier: "Dossier n°#{dossier.id}", date: updated_at.strftime('%d/%m %H:%M'), type: type } + end +end diff --git a/app/facades/dossier_facades.rb b/app/facades/dossier_facades.rb index b0b622ae6..6893f4bcb 100644 --- a/app/facades/dossier_facades.rb +++ b/app/facades/dossier_facades.rb @@ -10,6 +10,10 @@ class DossierFacades @dossier.decorate end + def last_notifications + @dossier.notifications.order("updated_at DESC").limit(5) + end + def champs @dossier.ordered_champs end diff --git a/app/facades/dossiers_list_facades.rb b/app/facades/dossiers_list_facades.rb index b07b8652c..d32cb0eb4 100644 --- a/app/facades/dossiers_list_facades.rb +++ b/app/facades/dossiers_list_facades.rb @@ -138,4 +138,4 @@ class DossiersListFacades @procedure.nil? ? backoffice_dossiers_path(liste: liste) : backoffice_dossiers_procedure_path(id: @procedure.id, liste: liste) end -end \ No newline at end of file +end diff --git a/app/models/gestionnaire.rb b/app/models/gestionnaire.rb index 10a6953af..580dc1b96 100644 --- a/app/models/gestionnaire.rb +++ b/app/models/gestionnaire.rb @@ -64,7 +64,7 @@ class Gestionnaire < ActiveRecord::Base end def notifications - Notification.where(already_read: false, dossier_id: follows.pluck(:dossier_id) ) + Notification.where(already_read: false, dossier_id: follows.pluck(:dossier_id) ).order("updated_at DESC") end def notifications_for procedure diff --git a/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_index.html.haml b/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_index.html.haml index cfdc87824..e715a6ae6 100644 --- a/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_index.html.haml +++ b/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_index.html.haml @@ -11,8 +11,7 @@ %div#menu-block %div.split-hr-left #switch-buttons - #switch-procedures Procédures - | + #switch-procedures.active Procédures #switch-notifications Notifications %div#infos-block @@ -29,4 +28,10 @@ -if procedure[:unread_notifications] > 0 .badge.progress-bar-warning{title: 'Notifications'} = procedure[:unread_notifications] - + #notifications_list.hidden + - @facade_data_view.unread_notifications.each do |notification| + = link_to backoffice_dossier_path(notification.dossier.id) do + .notification + .dossier= notification.decorate.index_display[:dossier] + .updated-at= notification.decorate.index_display[:date] + .type= notification.decorate.index_display[:type] diff --git a/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_show.html.haml b/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_show.html.haml index be7e47390..6c2fd2e66 100644 --- a/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_show.html.haml +++ b/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_show.html.haml @@ -34,7 +34,7 @@ = "Aucune notification pour le moment." - else %i.fa.fa-bell-o - - @facade.dossier.notifications.limit(5).each do |notification| + - @facade.last_notifications.each do |notification| .notification .updated-at= notification.updated_at.strftime('%d/%m/%Y %H:%M') - if ['champs'].include?(notification.type_notif) From e7b76523880eaba8a08699986ad6153b1d9a3427 Mon Sep 17 00:00:00 2001 From: Xavier J Date: Tue, 27 Dec 2016 15:50:45 +0100 Subject: [PATCH 30/30] Fix some tests --- app/facades/invite_dossier_facades.rb | 2 +- spec/controllers/users/description_controller_spec.rb | 2 +- spec/controllers/users/dossiers/invites_controller_spec.rb | 2 +- spec/models/notification_spec.rb | 1 - spec/spec_helper.rb | 2 +- spec/views/admin/gestionnaires/index.html.haml_spec.rb | 2 +- 6 files changed, 5 insertions(+), 6 deletions(-) diff --git a/app/facades/invite_dossier_facades.rb b/app/facades/invite_dossier_facades.rb index 63e9b5a61..cda91257e 100644 --- a/app/facades/invite_dossier_facades.rb +++ b/app/facades/invite_dossier_facades.rb @@ -2,6 +2,6 @@ class InviteDossierFacades < DossierFacades #TODO rechercher en fonction de la personne/email def initialize dossier_id, email - @dossier = (Invite.where(email: email).find(dossier_id)).dossier + @dossier = Invite.where(email: email, dossier_id: dossier_id).first!.dossier end end \ No newline at end of file diff --git a/spec/controllers/users/description_controller_spec.rb b/spec/controllers/users/description_controller_spec.rb index b459d6341..ace2b9f1b 100644 --- a/spec/controllers/users/description_controller_spec.rb +++ b/spec/controllers/users/description_controller_spec.rb @@ -7,7 +7,7 @@ describe Users::DescriptionController, type: :controller, vcr: {cassette_name: ' let(:invite_by_user) { create :user, email: 'invite@plop.com' } let(:procedure) { create(:procedure, :with_two_type_de_piece_justificative, :with_type_de_champ, :with_datetime, cerfa_flag: true) } - let(:dossier) { create(:dossier, procedure: procedure, user: owner_user) } + let(:dossier) { create(:dossier, procedure: procedure, user: owner_user, state: 'initiated') } let(:dossier_id) { dossier.id } let(:bad_dossier_id) { Dossier.count + 10000 } diff --git a/spec/controllers/users/dossiers/invites_controller_spec.rb b/spec/controllers/users/dossiers/invites_controller_spec.rb index 70bfcbc70..e2d71450a 100644 --- a/spec/controllers/users/dossiers/invites_controller_spec.rb +++ b/spec/controllers/users/dossiers/invites_controller_spec.rb @@ -1,4 +1,4 @@ -RSpec.describe Users::Dossiers::InvitesController, type: :controller do +describe Users::Dossiers::InvitesController, type: :controller do describe '#authenticate_user!' do let(:user) { create :user } let(:invite) { create :invite } diff --git a/spec/models/notification_spec.rb b/spec/models/notification_spec.rb index 8adf11ab2..0a945ff9f 100644 --- a/spec/models/notification_spec.rb +++ b/spec/models/notification_spec.rb @@ -3,7 +3,6 @@ require 'spec_helper' describe Notification do it { is_expected.to have_db_column(:already_read) } it { is_expected.to have_db_column(:liste) } - it { is_expected.to have_db_column(:multiple) } it { is_expected.to have_db_column(:type_notif) } it { is_expected.to have_db_column(:created_at) } it { is_expected.to have_db_column(:updated_at) } diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index d999bf456..4e7319f2a 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -41,7 +41,7 @@ Capybara.register_driver :poltergeist do |app| Capybara::Poltergeist::Driver.new(app, js_errors: true, port: 44_678 + ENV['TEST_ENV_NUMBER'].to_i, phantomjs_options: ['--proxy-type=none'], timeout: 180) end -#ActiveSupport::Deprecation.silenced = true +ActiveSupport::Deprecation.silenced = true Capybara.default_max_wait_time = 1 diff --git a/spec/views/admin/gestionnaires/index.html.haml_spec.rb b/spec/views/admin/gestionnaires/index.html.haml_spec.rb index 222b43b2c..9c57ee063 100644 --- a/spec/views/admin/gestionnaires/index.html.haml_spec.rb +++ b/spec/views/admin/gestionnaires/index.html.haml_spec.rb @@ -29,6 +29,6 @@ describe 'admin/gestionnaires/index.html.haml', type: :view do array: true)) render end - it { expect(rendered).to match(/plop\d+@plop.com/) } + it { expect(rendered).to match(/gest\d+@plop.com/) } end end \ No newline at end of file