commit
408124d61c
17 changed files with 4206 additions and 184 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -34,3 +34,7 @@ vendor/*
|
||||||
/yarn-error.log
|
/yarn-error.log
|
||||||
yarn-debug.log*
|
yarn-debug.log*
|
||||||
.yarn-integrity
|
.yarn-integrity
|
||||||
|
/docs
|
||||||
|
|
||||||
|
# Local Netlify folder
|
||||||
|
.netlify
|
||||||
|
|
|
@ -454,7 +454,7 @@ GEM
|
||||||
ast (~> 2.4.1)
|
ast (~> 2.4.1)
|
||||||
pdf-core (0.7.0)
|
pdf-core (0.7.0)
|
||||||
pg (1.2.3)
|
pg (1.2.3)
|
||||||
phonelib (0.6.43)
|
phonelib (0.6.45)
|
||||||
prawn (2.2.2)
|
prawn (2.2.2)
|
||||||
pdf-core (~> 0.7.0)
|
pdf-core (~> 0.7.0)
|
||||||
ttfunk (~> 1.5)
|
ttfunk (~> 1.5)
|
||||||
|
|
|
@ -30,17 +30,16 @@ module Instructeurs
|
||||||
.reorder(nil)
|
.reorder(nil)
|
||||||
.count
|
.count
|
||||||
|
|
||||||
@all_dossiers_counts = {}
|
@all_dossiers_counts = {
|
||||||
@all_dossiers_counts['à suivre'] = dossiers.without_followers.en_cours.count
|
'à suivre' => @dossiers_a_suivre_count_per_procedure.sum { |_, v| v },
|
||||||
@all_dossiers_counts['suivis'] = current_instructeur
|
'suivis' => @followed_dossiers_count_per_procedure.sum { |_, v| v },
|
||||||
.followed_dossiers
|
'traités' => @dossiers_termines_count_per_procedure.sum { |_, v| v },
|
||||||
.joins(:groupe_instructeur)
|
'dossiers' => @dossiers_count_per_procedure.sum { |_, v| v },
|
||||||
.en_cours
|
'archivés' => @dossiers_archived_count_per_procedure.sum { |_, v| v }
|
||||||
.where(groupe_instructeur_id: groupe_ids)
|
}
|
||||||
.count
|
|
||||||
@all_dossiers_counts['traités'] = dossiers.termine.count
|
@procedure_ids_en_cours_with_notifications = current_instructeur.procedure_ids_with_notifications(:en_cours)
|
||||||
@all_dossiers_counts['dossiers'] = dossiers.all_state.count
|
@procedure_ids_termines_with_notifications = current_instructeur.procedure_ids_with_notifications(:termine)
|
||||||
@all_dossiers_counts['archivés'] = dossiers.archived.count
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
|
|
|
@ -20,5 +20,5 @@ class Champs::PhoneChamp < Champs::TextChamp
|
||||||
possible: true,
|
possible: true,
|
||||||
allow_blank: true,
|
allow_blank: true,
|
||||||
message: I18n.t(:not_a_phone, scope: 'activerecord.errors.messages')
|
message: I18n.t(:not_a_phone, scope: 'activerecord.errors.messages')
|
||||||
}
|
}, unless: -> { Phonelib.valid_for_country?(value, :pf) }
|
||||||
end
|
end
|
||||||
|
|
|
@ -144,17 +144,14 @@ class Instructeur < ApplicationRecord
|
||||||
.with_notifications(self)
|
.with_notifications(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
def procedures_with_notifications(scope)
|
def procedure_ids_with_notifications(scope)
|
||||||
dossiers = Dossier
|
groupe_instructeur_ids = Dossier
|
||||||
.send(scope) # :en_cours or :termine (or any other Dossier scope)
|
.send(scope) # :en_cours or :termine (or any other Dossier scope)
|
||||||
.merge(followed_dossiers)
|
.merge(followed_dossiers)
|
||||||
.with_notifications(self)
|
.with_notifications(self)
|
||||||
|
.select(:groupe_instructeur_id)
|
||||||
|
|
||||||
Procedure
|
GroupeInstructeur.where(id: groupe_instructeur_ids).pluck(:procedure_id)
|
||||||
.where(id: dossiers.joins(:groupe_instructeur)
|
|
||||||
.select('groupe_instructeurs.procedure_id')
|
|
||||||
.distinct)
|
|
||||||
.distinct
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def mark_tab_as_seen(dossier, tab)
|
def mark_tab_as_seen(dossier, tab)
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
%ul.procedure-list
|
%li.procedure-item.flex.align-start
|
||||||
- procedures.each do |p|
|
|
||||||
%li.procedure-item.flex.align-start
|
|
||||||
= link_to(instructeur_procedure_path(p)) do
|
= link_to(instructeur_procedure_path(p)) do
|
||||||
.flex
|
.flex
|
||||||
|
|
||||||
|
@ -21,7 +19,7 @@
|
||||||
%li
|
%li
|
||||||
%object
|
%object
|
||||||
= link_to(instructeur_procedure_path(p, statut: 'suivis')) do
|
= link_to(instructeur_procedure_path(p, statut: 'suivis')) do
|
||||||
- if current_instructeur.procedures_with_notifications(:en_cours).include?(p)
|
- if procedure_ids_en_cours_with_notifications.include?(p.id)
|
||||||
%span.notifications{ 'aria-label': "notifications" }
|
%span.notifications{ 'aria-label': "notifications" }
|
||||||
- followed_count = followed_dossiers_count_per_procedure[p.id] || 0
|
- followed_count = followed_dossiers_count_per_procedure[p.id] || 0
|
||||||
.stats-number
|
.stats-number
|
||||||
|
@ -31,7 +29,7 @@
|
||||||
%li
|
%li
|
||||||
%object
|
%object
|
||||||
= link_to(instructeur_procedure_path(p, statut: 'traites')) do
|
= link_to(instructeur_procedure_path(p, statut: 'traites')) do
|
||||||
- if current_instructeur.procedures_with_notifications(:termine).include?(p)
|
- if procedure_ids_termines_with_notifications.include?(p.id)
|
||||||
%span.notifications{ 'aria-label': "notifications" }
|
%span.notifications{ 'aria-label': "notifications" }
|
||||||
- termines_count = dossiers_termines_count_per_procedure[p.id] || 0
|
- termines_count = dossiers_termines_count_per_procedure[p.id] || 0
|
||||||
.stats-number
|
.stats-number
|
||||||
|
|
|
@ -4,9 +4,14 @@
|
||||||
%h1.page-title Démarches
|
%h1.page-title Démarches
|
||||||
= render partial: 'instructeurs/procedures/synthese', locals: { procedures: @procedures, all_dossiers_counts: @all_dossiers_counts }
|
= render partial: 'instructeurs/procedures/synthese', locals: { procedures: @procedures, all_dossiers_counts: @all_dossiers_counts }
|
||||||
|
|
||||||
= render partial: 'instructeurs/procedures/list', locals: { procedures: @procedures,
|
%ul.procedure-list
|
||||||
dossiers_count_per_procedure: @dossiers_count_per_procedure,
|
= render partial: 'instructeurs/procedures/list',
|
||||||
|
collection: @procedures,
|
||||||
|
as: :p,
|
||||||
|
locals: { dossiers_count_per_procedure: @dossiers_count_per_procedure,
|
||||||
dossiers_a_suivre_count_per_procedure: @dossiers_a_suivre_count_per_procedure,
|
dossiers_a_suivre_count_per_procedure: @dossiers_a_suivre_count_per_procedure,
|
||||||
dossiers_archived_count_per_procedure: @dossiers_archived_count_per_procedure,
|
dossiers_archived_count_per_procedure: @dossiers_archived_count_per_procedure,
|
||||||
dossiers_termines_count_per_procedure: @dossiers_termines_count_per_procedure,
|
dossiers_termines_count_per_procedure: @dossiers_termines_count_per_procedure,
|
||||||
followed_dossiers_count_per_procedure: @followed_dossiers_count_per_procedure }
|
followed_dossiers_count_per_procedure: @followed_dossiers_count_per_procedure,
|
||||||
|
procedure_ids_en_cours_with_notifications: @procedure_ids_en_cours_with_notifications,
|
||||||
|
procedure_ids_termines_with_notifications: @procedure_ids_termines_with_notifications }
|
||||||
|
|
|
@ -19,9 +19,13 @@ max_logo_width = body_width
|
||||||
max_logo_height = 50.mm
|
max_logo_height = 50.mm
|
||||||
max_signature_size = 50.mm
|
max_signature_size = 50.mm
|
||||||
|
|
||||||
title = @attestation.fetch(:title)
|
def normalize_pdf_text(text)
|
||||||
body = @attestation.fetch(:body)
|
text&.tr("\t", ' ')
|
||||||
footer = @attestation.fetch(:footer)
|
end
|
||||||
|
|
||||||
|
title = normalize_pdf_text(@attestation.fetch(:title))
|
||||||
|
body = normalize_pdf_text(@attestation.fetch(:body))
|
||||||
|
footer = normalize_pdf_text(@attestation.fetch(:footer))
|
||||||
created_at = @attestation.fetch(:created_at)
|
created_at = @attestation.fetch(:created_at)
|
||||||
|
|
||||||
logo = @attestation[:logo]
|
logo = @attestation[:logo]
|
||||||
|
|
|
@ -225,7 +225,7 @@
|
||||||
.cta-panel-wrapper
|
.cta-panel-wrapper
|
||||||
%div
|
%div
|
||||||
%h1.cta-panel-title Une question, un problème ?
|
%h1.cta-panel-title Une question, un problème ?
|
||||||
%p.cta-panel-explanation Notre équipe est disponible pour vous renseigner et vous aider
|
%p.cta-panel-explanation Consultez notre FAQ
|
||||||
%div
|
%div
|
||||||
%a.cta-panel-button-white{ rel: 'noopener noreferrer', href:'/contact-admin' }
|
%a.cta-panel-button-white{ rel: 'noopener noreferrer', href:"#{ FAQ_URL }" }
|
||||||
Contactez-nous
|
Voir la FAQ
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
%ul.numbers
|
%ul.numbers
|
||||||
%li.number
|
%li.number
|
||||||
.number-value
|
.number-value
|
||||||
= number_with_delimiter(Procedure.includes(:administrateurs).publiees_ou_closes.flat_map(&:administrateurs).uniq.count, :locale => :fr)
|
= number_with_delimiter(AdministrateursProcedure.joins(:procedure).merge(Procedure.publiees_ou_closes).select('distinct administrateur_id').count, :locale => :fr)
|
||||||
.number-label<
|
.number-label<
|
||||||
administrations
|
administrations
|
||||||
%br<>
|
%br<>
|
||||||
|
|
11
package.json
11
package.json
|
@ -38,6 +38,7 @@
|
||||||
"whatwg-fetch": "^3.0.0"
|
"whatwg-fetch": "^3.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@2fd/graphdoc": "^2.4.0",
|
||||||
"babel-eslint": "^10.1.0",
|
"babel-eslint": "^10.1.0",
|
||||||
"eclint": "^2.8.1",
|
"eclint": "^2.8.1",
|
||||||
"eslint": "^7.0.0",
|
"eslint": "^7.0.0",
|
||||||
|
@ -45,6 +46,7 @@
|
||||||
"eslint-plugin-prettier": "^3.1.3",
|
"eslint-plugin-prettier": "^3.1.3",
|
||||||
"eslint-plugin-react": "^7.20.0",
|
"eslint-plugin-react": "^7.20.0",
|
||||||
"eslint-plugin-react-hooks": "^4.0.2",
|
"eslint-plugin-react-hooks": "^4.0.2",
|
||||||
|
"netlify-cli": "^2.61.2",
|
||||||
"prettier": "^2.0.5",
|
"prettier": "^2.0.5",
|
||||||
"webpack-bundle-analyzer": "^3.7.0",
|
"webpack-bundle-analyzer": "^3.7.0",
|
||||||
"webpack-dev-server": "^3.11.0"
|
"webpack-dev-server": "^3.11.0"
|
||||||
|
@ -52,9 +54,16 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"lint:ec": "eclint check $({ git ls-files | grep -v app/graphql/schema.graphql ; find vendor -type f ; echo 'db/schema.rb' ; } | sort | uniq -u)",
|
"lint:ec": "eclint check $({ git ls-files | grep -v app/graphql/schema.graphql ; find vendor -type f ; echo 'db/schema.rb' ; } | sort | uniq -u)",
|
||||||
"lint:js": "eslint ./app/javascript ./app/assets/javascripts ./config/webpack",
|
"lint:js": "eslint ./app/javascript ./app/assets/javascripts ./config/webpack",
|
||||||
"webpack:build": "NODE_ENV=production bin/webpack"
|
"webpack:build": "NODE_ENV=production bin/webpack",
|
||||||
|
"graphql:docs:build": "graphdoc --force",
|
||||||
|
"graphql:docs:deploy": "netlify deploy -d ./docs/graphql --prod",
|
||||||
|
"graphql:docs:publish": "yarn graphql:docs:build && yarn graphql:docs:deploy"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 12.*"
|
"node": ">= 12.*"
|
||||||
|
},
|
||||||
|
"graphdoc": {
|
||||||
|
"endpoint": "https://www.demarches-simplifiees.fr/api/v2/graphql",
|
||||||
|
"output": "./docs/graphql"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -698,6 +698,43 @@ describe Users::DossiersController, type: :controller do
|
||||||
expect(instructeur.reload.followed_dossiers.with_notifications(instructeur)).to eq([dossier.reload])
|
expect(instructeur.reload.followed_dossiers.with_notifications(instructeur)).to eq([dossier.reload])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when the champ is a phone number' do
|
||||||
|
let(:procedure) { create(:procedure, :published, :with_phone) }
|
||||||
|
let!(:dossier) { create(:dossier, :en_construction, user: user, procedure: procedure) }
|
||||||
|
let(:first_champ) { dossier.champs.first }
|
||||||
|
let(:now) { Time.zone.parse('01/01/2100') }
|
||||||
|
|
||||||
|
let(:submit_payload) do
|
||||||
|
{
|
||||||
|
id: dossier.id,
|
||||||
|
dossier: {
|
||||||
|
champs_attributes: [
|
||||||
|
{
|
||||||
|
id: first_champ.id,
|
||||||
|
value: value
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with a valid value sent as string' do
|
||||||
|
let(:value) { '0612345678' }
|
||||||
|
it 'updates the value' do
|
||||||
|
subject
|
||||||
|
expect(first_champ.reload.value).to eq('0612345678')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with a valid value sent as number' do
|
||||||
|
let(:value) { '45187272'.to_i }
|
||||||
|
it 'updates the value' do
|
||||||
|
subject
|
||||||
|
expect(first_champ.reload.value).to eq('45187272')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#index' do
|
describe '#index' do
|
||||||
|
|
|
@ -182,6 +182,12 @@ FactoryBot.define do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
trait :with_phone do
|
||||||
|
after(:build) do |procedure, _evaluator|
|
||||||
|
build(:type_de_champ_phone, procedure: procedure)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
trait :published do
|
trait :published do
|
||||||
after(:build) do |procedure, _evaluator|
|
after(:build) do |procedure, _evaluator|
|
||||||
procedure.path = generate(:published_path)
|
procedure.path = generate(:published_path)
|
||||||
|
|
|
@ -13,7 +13,23 @@ RSpec.describe ApplicationJob, type: :job do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when ::Excon::Error::BadRequest is raised' do
|
||||||
|
# https://api.rubyonrails.org/classes/ActiveJob/Exceptions/ClassMethods.html#method-i-retry_on
|
||||||
|
# retry on will try 5 times and then bubble up the error
|
||||||
|
it 'makes 5 attempts' do
|
||||||
|
assert_performed_jobs 5 do
|
||||||
|
ExconErrJob.perform_later rescue ::Excon::Error::BadRequest
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
class ChildJob < ApplicationJob
|
class ChildJob < ApplicationJob
|
||||||
def perform; end
|
def perform; end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class ExconErrJob < ApplicationJob
|
||||||
|
def perform
|
||||||
|
raise ::Excon::Error::BadRequest.new('bad request')
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -20,6 +20,19 @@ describe Champs::PhoneChamp do
|
||||||
expect(build(:champ_phone, value: "+1(0) - 123456789")).to be_valid
|
expect(build(:champ_phone, value: "+1(0) - 123456789")).to be_valid
|
||||||
expect(build(:champ_phone, value: "+49 2109 87654321")).to be_valid
|
expect(build(:champ_phone, value: "+49 2109 87654321")).to be_valid
|
||||||
expect(build(:champ_phone, value: "012345678")).to be_valid
|
expect(build(:champ_phone, value: "012345678")).to be_valid
|
||||||
|
# polynesian numbers should not return errors in any way
|
||||||
|
## landline numbers start with 40 or 45
|
||||||
|
expect(build(:champ_phone, value: "45187272")).to be_valid
|
||||||
|
expect(build(:champ_phone, value: "40 473 500")).to be_valid
|
||||||
|
expect(build(:champ_phone, value: "40473500")).to be_valid
|
||||||
|
expect(build(:champ_phone, value: "45473500")).to be_valid
|
||||||
|
## +689 is the international indicator
|
||||||
|
expect(build(:champ_phone, value: "+689 45473500")).to be_valid
|
||||||
|
expect(build(:champ_phone, value: "0145473500")).to be_valid
|
||||||
|
## polynesian mobile numbers start with 87, 88, 89
|
||||||
|
expect(build(:champ_phone, value: "87473500")).to be_valid
|
||||||
|
expect(build(:champ_phone, value: "88473500")).to be_valid
|
||||||
|
expect(build(:champ_phone, value: "89473500")).to be_valid
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -352,17 +352,17 @@ describe Instructeur, type: :model do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#notifications_per_procedure' do
|
describe '#procedure_ids_with_notifications' do
|
||||||
let!(:dossier) { create(:dossier, :followed, state: Dossier.states.fetch(:en_construction)) }
|
let!(:dossier) { create(:dossier, :followed, state: Dossier.states.fetch(:en_construction)) }
|
||||||
let(:instructeur) { dossier.follows.first.instructeur }
|
let(:instructeur) { dossier.follows.first.instructeur }
|
||||||
let(:procedure) { dossier.procedure }
|
let(:procedure) { dossier.procedure }
|
||||||
|
|
||||||
subject { instructeur.procedures_with_notifications(:en_cours) }
|
subject { instructeur.procedure_ids_with_notifications(:en_cours) }
|
||||||
|
|
||||||
context 'when there is a modification on public champs' do
|
context 'when there is a modification on public champs' do
|
||||||
before { dossier.update!(last_champ_updated_at: Time.zone.now) }
|
before { dossier.update!(last_champ_updated_at: Time.zone.now) }
|
||||||
|
|
||||||
it { is_expected.to match([procedure]) }
|
it { is_expected.to match([procedure.id]) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue