commit
de133bfa68
72 changed files with 404 additions and 400 deletions
2
Gemfile
2
Gemfile
|
@ -76,7 +76,7 @@ gem 'zipline'
|
||||||
gem 'zxcvbn-ruby', require: 'zxcvbn'
|
gem 'zxcvbn-ruby', require: 'zxcvbn'
|
||||||
|
|
||||||
group :test do
|
group :test do
|
||||||
gem 'capybara', '3.13.2' # Integration testing
|
gem 'capybara' # Integration testing
|
||||||
gem 'capybara-email' # Access emails during integration tests
|
gem 'capybara-email' # Access emails during integration tests
|
||||||
gem 'capybara-screenshot' # Save a dump of the page when an integration test fails
|
gem 'capybara-screenshot' # Save a dump of the page when an integration test fails
|
||||||
gem 'capybara-selenium'
|
gem 'capybara-selenium'
|
||||||
|
|
|
@ -119,13 +119,13 @@ GEM
|
||||||
browser (2.5.3)
|
browser (2.5.3)
|
||||||
builder (3.2.3)
|
builder (3.2.3)
|
||||||
byebug (10.0.2)
|
byebug (10.0.2)
|
||||||
capybara (3.13.2)
|
capybara (3.29.0)
|
||||||
addressable
|
addressable
|
||||||
mini_mime (>= 0.1.3)
|
mini_mime (>= 0.1.3)
|
||||||
nokogiri (~> 1.8)
|
nokogiri (~> 1.8)
|
||||||
rack (>= 1.6.0)
|
rack (>= 1.6.0)
|
||||||
rack-test (>= 0.6.3)
|
rack-test (>= 0.6.3)
|
||||||
regexp_parser (~> 1.2)
|
regexp_parser (~> 1.5)
|
||||||
xpath (~> 3.2)
|
xpath (~> 3.2)
|
||||||
capybara-email (3.0.1)
|
capybara-email (3.0.1)
|
||||||
capybara (>= 2.4, < 4.0)
|
capybara (>= 2.4, < 4.0)
|
||||||
|
@ -719,7 +719,7 @@ DEPENDENCIES
|
||||||
brakeman
|
brakeman
|
||||||
browser
|
browser
|
||||||
byebug
|
byebug
|
||||||
capybara (= 3.13.2)
|
capybara
|
||||||
capybara-email
|
capybara-email
|
||||||
capybara-screenshot
|
capybara-screenshot
|
||||||
capybara-selenium
|
capybara-selenium
|
||||||
|
|
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 28 KiB |
|
@ -23,29 +23,28 @@ $header-mobile-breakpoint: 550px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-logo {
|
.header-logo {
|
||||||
display: inline-block;
|
display: flex;
|
||||||
height: 100%;
|
flex-wrap: wrap;
|
||||||
background-size: contain;
|
|
||||||
background-position: center;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
|
|
||||||
// Logo large
|
img {
|
||||||
background-image: image-url("header/logo-ds-wide.svg");
|
margin-right: 10px;
|
||||||
width: 360px;
|
|
||||||
margin-right: 4 * $default-spacer;
|
|
||||||
|
|
||||||
// Logo normal
|
|
||||||
@media (max-width: $header-landing-breakpoint) {
|
|
||||||
background-image: image-url("header/logo-ds.svg");
|
|
||||||
width: 132px;
|
|
||||||
margin-right: $default-spacer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Logo narrow
|
.site-title {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: bold;
|
||||||
|
|
||||||
|
&.small {
|
||||||
|
@media (min-width: $header-mobile-breakpoint) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.big {
|
||||||
@media (max-width: $header-mobile-breakpoint) {
|
@media (max-width: $header-mobile-breakpoint) {
|
||||||
background-image: image-url("header/logo-ds-narrow.svg");
|
display: none;
|
||||||
width: 32px;
|
}
|
||||||
margin-right: 0;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,15 +9,21 @@
|
||||||
text-indent: -9999em;
|
text-indent: -9999em;
|
||||||
animation: load4 1.3s infinite linear;
|
animation: load4 1.3s infinite linear;
|
||||||
transform: translateZ(0);
|
transform: translateZ(0);
|
||||||
}
|
|
||||||
|
|
||||||
.right-spinner {
|
&.right {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 3.7em;
|
top: 3.7em;
|
||||||
right: 1.2em;
|
right: 1.2em;
|
||||||
transform: scale(0.3);
|
transform: scale(0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.left {
|
||||||
|
top: 1.2em;
|
||||||
|
left: 1.2em;
|
||||||
|
transform: scale(0.4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@keyframes load4 {
|
@keyframes load4 {
|
||||||
0%,
|
0%,
|
||||||
100% {
|
100% {
|
||||||
|
|
|
@ -19,7 +19,7 @@ class Admin::ProceduresController < AdminController
|
||||||
|
|
||||||
def archived
|
def archived
|
||||||
@procedures = smart_listing_create :procedures,
|
@procedures = smart_listing_create :procedures,
|
||||||
current_administrateur.procedures.archivees.order(published_at: :desc),
|
current_administrateur.procedures.closes.order(published_at: :desc),
|
||||||
partial: "admin/procedures/list",
|
partial: "admin/procedures/list",
|
||||||
array: true
|
array: true
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ class Admin::ProceduresController < AdminController
|
||||||
def destroy
|
def destroy
|
||||||
procedure = current_administrateur.procedures.find(params[:id])
|
procedure = current_administrateur.procedures.find(params[:id])
|
||||||
|
|
||||||
if procedure.publiee_ou_archivee?
|
if procedure.publiee_ou_close?
|
||||||
return render json: {}, status: 401
|
return render json: {}, status: 401
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -95,9 +95,9 @@ class Admin::ProceduresController < AdminController
|
||||||
|
|
||||||
def archive
|
def archive
|
||||||
procedure = current_administrateur.procedures.find(params[:procedure_id])
|
procedure = current_administrateur.procedures.find(params[:procedure_id])
|
||||||
procedure.archive!
|
procedure.close!
|
||||||
|
|
||||||
flash.notice = "Démarche archivée"
|
flash.notice = "Démarche close"
|
||||||
redirect_to admin_procedures_path
|
redirect_to admin_procedures_path
|
||||||
|
|
||||||
rescue ActiveRecord::RecordNotFound
|
rescue ActiveRecord::RecordNotFound
|
||||||
|
@ -131,7 +131,7 @@ class Admin::ProceduresController < AdminController
|
||||||
|
|
||||||
def new_from_existing
|
def new_from_existing
|
||||||
significant_procedure_ids = Procedure
|
significant_procedure_ids = Procedure
|
||||||
.publiees_ou_archivees
|
.publiees_ou_closes
|
||||||
.joins(:dossiers)
|
.joins(:dossiers)
|
||||||
.group("procedures.id")
|
.group("procedures.id")
|
||||||
.having("count(dossiers.id) >= ?", SIGNIFICANT_DOSSIERS_THRESHOLD)
|
.having("count(dossiers.id) >= ?", SIGNIFICANT_DOSSIERS_THRESHOLD)
|
||||||
|
|
|
@ -285,7 +285,7 @@ class ApplicationController < ActionController::Base
|
||||||
DS_ID: current_administrateur&.id,
|
DS_ID: current_administrateur&.id,
|
||||||
DS_NB_DEMARCHES_BROUILLONS: nb_demarches_by_state['brouillon'],
|
DS_NB_DEMARCHES_BROUILLONS: nb_demarches_by_state['brouillon'],
|
||||||
DS_NB_DEMARCHES_ACTIVES: nb_demarches_by_state['publiee'],
|
DS_NB_DEMARCHES_ACTIVES: nb_demarches_by_state['publiee'],
|
||||||
DS_NB_DEMARCHES_ARCHIVES: nb_demarches_by_state['archivee']
|
DS_NB_DEMARCHES_ARCHIVES: nb_demarches_by_state['close']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,7 +10,7 @@ module Instructeurs
|
||||||
.procedures
|
.procedures
|
||||||
.with_attached_logo
|
.with_attached_logo
|
||||||
.includes(:defaut_groupe_instructeur)
|
.includes(:defaut_groupe_instructeur)
|
||||||
.order(archived_at: :desc, published_at: :desc, created_at: :desc)
|
.order(closed_at: :desc, archived_at: :desc, published_at: :desc, created_at: :desc)
|
||||||
|
|
||||||
dossiers = current_instructeur.dossiers.joins(:groupe_instructeur)
|
dossiers = current_instructeur.dossiers.joins(:groupe_instructeur)
|
||||||
@dossiers_count_per_procedure = dossiers.all_state.group('groupe_instructeurs.procedure_id').reorder(nil).count
|
@dossiers_count_per_procedure = dossiers.all_state.group('groupe_instructeurs.procedure_id').reorder(nil).count
|
||||||
|
|
|
@ -22,16 +22,6 @@ module Manager
|
||||||
redirect_to manager_procedure_path(procedure)
|
redirect_to manager_procedure_path(procedure)
|
||||||
end
|
end
|
||||||
|
|
||||||
def draft
|
|
||||||
if procedure.dossiers.empty?
|
|
||||||
procedure.draft!
|
|
||||||
flash[:notice] = "La démarche a bien été passée en brouillon."
|
|
||||||
else
|
|
||||||
flash[:alert] = "Impossible de repasser en brouillon une démarche à laquelle sont rattachés des dossiers."
|
|
||||||
end
|
|
||||||
redirect_to manager_procedure_path(procedure)
|
|
||||||
end
|
|
||||||
|
|
||||||
def hide
|
def hide
|
||||||
procedure.hide!
|
procedure.hide!
|
||||||
flash[:notice] = "La démarche a bien été supprimée, en cas d'erreur contactez un développeur."
|
flash[:notice] = "La démarche a bien été supprimée, en cas d'erreur contactez un développeur."
|
||||||
|
|
|
@ -49,7 +49,8 @@ module NewAdministrateur
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_instructeur
|
def add_instructeur
|
||||||
emails = params['emails'].map(&:strip).map(&:downcase)
|
emails = params['emails'].presence || []
|
||||||
|
emails = emails.map(&:strip).map(&:downcase)
|
||||||
|
|
||||||
correct_emails, bad_emails = emails
|
correct_emails, bad_emails = emails
|
||||||
.partition { |email| URI::MailTo::EMAIL_REGEXP.match?(email) }
|
.partition { |email| URI::MailTo::EMAIL_REGEXP.match?(email) }
|
||||||
|
|
|
@ -4,7 +4,7 @@ class StatsController < ApplicationController
|
||||||
MEAN_NUMBER_OF_CHAMPS_IN_A_FORM = 24.0
|
MEAN_NUMBER_OF_CHAMPS_IN_A_FORM = 24.0
|
||||||
|
|
||||||
def index
|
def index
|
||||||
procedures = Procedure.publiees_ou_archivees
|
procedures = Procedure.publiees_ou_closes
|
||||||
dossiers = Dossier.state_not_brouillon
|
dossiers = Dossier.state_not_brouillon
|
||||||
|
|
||||||
@procedures_numbers = procedures_numbers(procedures)
|
@procedures_numbers = procedures_numbers(procedures)
|
||||||
|
|
|
@ -53,7 +53,7 @@ module Users
|
||||||
def procedure_not_found
|
def procedure_not_found
|
||||||
procedure = Procedure.find_by(path: params[:path])
|
procedure = Procedure.find_by(path: params[:path])
|
||||||
|
|
||||||
if procedure&.archivee?
|
if procedure&.close?
|
||||||
flash.alert = t('errors.messages.procedure_archived')
|
flash.alert = t('errors.messages.procedure_archived')
|
||||||
else
|
else
|
||||||
flash.alert = t('errors.messages.procedure_not_found')
|
flash.alert = t('errors.messages.procedure_not_found')
|
||||||
|
|
|
@ -15,7 +15,8 @@ class AdministrateurDashboard < Administrate::BaseDashboard
|
||||||
procedures: Field::HasMany.with_options(limit: 20),
|
procedures: Field::HasMany.with_options(limit: 20),
|
||||||
registration_state: Field::String.with_options(searchable: false),
|
registration_state: Field::String.with_options(searchable: false),
|
||||||
current_sign_in_at: Field::DateTime,
|
current_sign_in_at: Field::DateTime,
|
||||||
features: FeaturesField
|
features: FeaturesField,
|
||||||
|
email: Field::Email
|
||||||
}.freeze
|
}.freeze
|
||||||
|
|
||||||
# COLLECTION_ATTRIBUTES
|
# COLLECTION_ATTRIBUTES
|
||||||
|
@ -46,7 +47,9 @@ class AdministrateurDashboard < Administrate::BaseDashboard
|
||||||
# FORM_ATTRIBUTES
|
# FORM_ATTRIBUTES
|
||||||
# an array of attributes that will be displayed
|
# an array of attributes that will be displayed
|
||||||
# on the model's form (`new` and `edit`) pages.
|
# on the model's form (`new` and `edit`) pages.
|
||||||
FORM_ATTRIBUTES = [].freeze
|
FORM_ATTRIBUTES = [
|
||||||
|
:email
|
||||||
|
].freeze
|
||||||
|
|
||||||
# Overwrite this method to customize how procedures are displayed
|
# Overwrite this method to customize how procedures are displayed
|
||||||
# across all pages of the admin dashboard.
|
# across all pages of the admin dashboard.
|
||||||
|
|
|
@ -26,7 +26,7 @@ class ProcedureDashboard < Administrate::BaseDashboard
|
||||||
auto_archive_on: Field::DateTime,
|
auto_archive_on: Field::DateTime,
|
||||||
published_at: Field::DateTime,
|
published_at: Field::DateTime,
|
||||||
hidden_at: Field::DateTime,
|
hidden_at: Field::DateTime,
|
||||||
archived_at: Field::DateTime,
|
closed_at: Field::DateTime,
|
||||||
whitelisted_at: Field::DateTime,
|
whitelisted_at: Field::DateTime,
|
||||||
service: Field::BelongsTo,
|
service: Field::BelongsTo,
|
||||||
initiated_mail_template: MailTemplateField,
|
initiated_mail_template: MailTemplateField,
|
||||||
|
@ -68,7 +68,7 @@ class ProcedureDashboard < Administrate::BaseDashboard
|
||||||
:published_at,
|
:published_at,
|
||||||
:whitelisted_at,
|
:whitelisted_at,
|
||||||
:hidden_at,
|
:hidden_at,
|
||||||
:archived_at,
|
:closed_at,
|
||||||
:types_de_champ,
|
:types_de_champ,
|
||||||
:types_de_champ_private,
|
:types_de_champ_private,
|
||||||
:for_individual,
|
:for_individual,
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
type Avis {
|
type Avis {
|
||||||
answer: String
|
|
||||||
attachmentUrl: URL
|
attachmentUrl: URL
|
||||||
createdAt: ISO8601DateTime!
|
dateQuestion: ISO8601DateTime!
|
||||||
email: String!
|
dateReponse: ISO8601DateTime
|
||||||
|
expert: Profile
|
||||||
id: ID!
|
id: ID!
|
||||||
|
instructeur: Profile!
|
||||||
question: String!
|
question: String!
|
||||||
|
reponse: String
|
||||||
}
|
}
|
||||||
|
|
||||||
type CarteChamp implements Champ {
|
type CarteChamp implements Champ {
|
||||||
|
@ -160,12 +162,30 @@ Une demarche
|
||||||
"""
|
"""
|
||||||
type Demarche {
|
type Demarche {
|
||||||
annotationDescriptors: [ChampDescriptor!]!
|
annotationDescriptors: [ChampDescriptor!]!
|
||||||
archivedAt: ISO8601DateTime
|
|
||||||
champDescriptors: [ChampDescriptor!]!
|
champDescriptors: [ChampDescriptor!]!
|
||||||
createdAt: ISO8601DateTime!
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Déscription de la démarche.
|
Date de la création.
|
||||||
|
"""
|
||||||
|
dateCreation: ISO8601DateTime!
|
||||||
|
|
||||||
|
"""
|
||||||
|
Date de la dernière modification.
|
||||||
|
"""
|
||||||
|
dateDerniereModification: ISO8601DateTime!
|
||||||
|
|
||||||
|
"""
|
||||||
|
Date de la fermeture.
|
||||||
|
"""
|
||||||
|
dateFermeture: ISO8601DateTime
|
||||||
|
|
||||||
|
"""
|
||||||
|
Date de la publication.
|
||||||
|
"""
|
||||||
|
datePublication: ISO8601DateTime!
|
||||||
|
|
||||||
|
"""
|
||||||
|
Description de la démarche.
|
||||||
"""
|
"""
|
||||||
description: String!
|
description: String!
|
||||||
|
|
||||||
|
@ -225,21 +245,24 @@ type Demarche {
|
||||||
L'état de la démarche.
|
L'état de la démarche.
|
||||||
"""
|
"""
|
||||||
state: DemarcheState!
|
state: DemarcheState!
|
||||||
|
|
||||||
|
"""
|
||||||
|
Le titre de la démarche.
|
||||||
|
"""
|
||||||
title: String!
|
title: String!
|
||||||
updatedAt: ISO8601DateTime!
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum DemarcheState {
|
enum DemarcheState {
|
||||||
"""
|
|
||||||
Archivée
|
|
||||||
"""
|
|
||||||
archivee
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Brouillon
|
Brouillon
|
||||||
"""
|
"""
|
||||||
brouillon
|
brouillon
|
||||||
|
|
||||||
|
"""
|
||||||
|
Close
|
||||||
|
"""
|
||||||
|
close
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Publiée
|
Publiée
|
||||||
"""
|
"""
|
||||||
|
@ -280,6 +303,11 @@ type Dossier {
|
||||||
avis: [Avis!]!
|
avis: [Avis!]!
|
||||||
champs: [Champ!]!
|
champs: [Champ!]!
|
||||||
|
|
||||||
|
"""
|
||||||
|
Date de la dernière modification.
|
||||||
|
"""
|
||||||
|
dateDerniereModification: ISO8601DateTime!
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Date de dépôt.
|
Date de dépôt.
|
||||||
"""
|
"""
|
||||||
|
@ -309,11 +337,6 @@ type Dossier {
|
||||||
L'état du dossier.
|
L'état du dossier.
|
||||||
"""
|
"""
|
||||||
state: DossierState!
|
state: DossierState!
|
||||||
|
|
||||||
"""
|
|
||||||
Date de dernière mise à jour.
|
|
||||||
"""
|
|
||||||
updatedAt: ISO8601DateTime!
|
|
||||||
usager: Profile!
|
usager: Profile!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
module Types
|
module Types
|
||||||
class AvisType < Types::BaseObject
|
class AvisType < Types::BaseObject
|
||||||
global_id_field :id
|
global_id_field :id
|
||||||
field :email, String, null: false
|
|
||||||
field :question, String, null: false, method: :introduction
|
field :question, String, null: false, method: :introduction
|
||||||
field :answer, String, null: true
|
field :reponse, String, null: true, method: :answer
|
||||||
field :created_at, GraphQL::Types::ISO8601DateTime, null: false
|
field :date_question, GraphQL::Types::ISO8601DateTime, null: false, method: :created_at
|
||||||
|
field :date_reponse, GraphQL::Types::ISO8601DateTime, null: true, method: :updated_at
|
||||||
|
|
||||||
field :attachment_url, Types::URL, null: true, extensions: [
|
field :attachment_url, Types::URL, null: true, extensions: [
|
||||||
{ Extensions::Attachment => { attachment: :piece_justificative_file } }
|
{ Extensions::Attachment => { attachment: :piece_justificative_file } }
|
||||||
]
|
]
|
||||||
|
|
||||||
|
field :instructeur, Types::ProfileType, null: false, method: :claimant
|
||||||
|
field :expert, Types::ProfileType, null: true, method: :instructeur
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,13 +10,14 @@ module Types
|
||||||
|
|
||||||
global_id_field :id
|
global_id_field :id
|
||||||
field :number, Int, "Le numero de la démarche.", null: false, method: :id
|
field :number, Int, "Le numero de la démarche.", null: false, method: :id
|
||||||
field :title, String, null: false, method: :libelle
|
field :title, String, "Le titre de la démarche.", null: false, method: :libelle
|
||||||
field :description, String, "Déscription de la démarche.", null: false
|
field :description, String, "Description de la démarche.", null: false
|
||||||
field :state, DemarcheState, "L'état de la démarche.", null: false
|
field :state, DemarcheState, "L'état de la démarche.", null: false
|
||||||
|
|
||||||
field :created_at, GraphQL::Types::ISO8601DateTime, null: false
|
field :date_creation, GraphQL::Types::ISO8601DateTime, "Date de la création.", null: false, method: :created_at
|
||||||
field :updated_at, GraphQL::Types::ISO8601DateTime, null: false
|
field :date_publication, GraphQL::Types::ISO8601DateTime, "Date de la publication.", null: false, method: :published_at
|
||||||
field :archived_at, GraphQL::Types::ISO8601DateTime, null: true
|
field :date_derniere_modification, GraphQL::Types::ISO8601DateTime, "Date de la dernière modification.", null: false, method: :updated_at
|
||||||
|
field :date_fermeture, GraphQL::Types::ISO8601DateTime, "Date de la fermeture.", null: true, method: :closed_at
|
||||||
|
|
||||||
field :groupe_instructeurs, [Types::GroupeInstructeurType], null: false
|
field :groupe_instructeurs, [Types::GroupeInstructeurType], null: false
|
||||||
|
|
||||||
|
|
|
@ -11,11 +11,11 @@ module Types
|
||||||
global_id_field :id
|
global_id_field :id
|
||||||
field :number, Int, "Le numero du dossier.", null: false, method: :id
|
field :number, Int, "Le numero du dossier.", null: false, method: :id
|
||||||
field :state, DossierState, "L'état du dossier.", null: false
|
field :state, DossierState, "L'état du dossier.", null: false
|
||||||
field :updated_at, GraphQL::Types::ISO8601DateTime, "Date de dernière mise à jour.", null: false
|
|
||||||
|
|
||||||
field :date_passage_en_construction, GraphQL::Types::ISO8601DateTime, "Date de dépôt.", null: false, method: :en_construction_at
|
field :date_passage_en_construction, GraphQL::Types::ISO8601DateTime, "Date de dépôt.", null: false, method: :en_construction_at
|
||||||
field :date_passage_en_instruction, GraphQL::Types::ISO8601DateTime, "Date de passage en instruction.", null: true, method: :en_instruction_at
|
field :date_passage_en_instruction, GraphQL::Types::ISO8601DateTime, "Date de passage en instruction.", null: true, method: :en_instruction_at
|
||||||
field :date_traitement, GraphQL::Types::ISO8601DateTime, "Date de traitement.", null: true, method: :processed_at
|
field :date_traitement, GraphQL::Types::ISO8601DateTime, "Date de traitement.", null: true, method: :processed_at
|
||||||
|
field :date_derniere_modification, GraphQL::Types::ISO8601DateTime, "Date de la dernière modification.", null: false, method: :updated_at
|
||||||
|
|
||||||
field :archived, Boolean, null: false
|
field :archived, Boolean, null: false
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ module DossierHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def dossier_submission_is_closed?(dossier)
|
def dossier_submission_is_closed?(dossier)
|
||||||
dossier.brouillon? && dossier.procedure.archivee?
|
dossier.brouillon? && dossier.procedure.close?
|
||||||
end
|
end
|
||||||
|
|
||||||
def dossier_display_state(dossier, lower: false)
|
def dossier_display_state(dossier, lower: false)
|
||||||
|
|
|
@ -14,7 +14,7 @@ module ProcedureHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def procedure_modal_text(procedure, key)
|
def procedure_modal_text(procedure, key)
|
||||||
action = procedure.archivee? ? :reopen : :publish
|
action = procedure.close? ? :reopen : :publish
|
||||||
t(action, scope: [:modal, :publish, key])
|
t(action, scope: [:modal, :publish, key])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
8
app/javascript/components/Loadable.js
Normal file
8
app/javascript/components/Loadable.js
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
import React from 'react';
|
||||||
|
import Loadable from 'react-loadable';
|
||||||
|
|
||||||
|
const loading = () => <div className="spinner left" />;
|
||||||
|
|
||||||
|
export default function(loader) {
|
||||||
|
return Loadable({ loader, loading });
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
import React, { Component } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { library } from '@fortawesome/fontawesome-svg-core';
|
||||||
|
import {
|
||||||
|
faArrowCircleDown,
|
||||||
|
faArrowDown,
|
||||||
|
faArrowsAltV,
|
||||||
|
faArrowUp,
|
||||||
|
faPlus,
|
||||||
|
faTrash
|
||||||
|
} from '@fortawesome/free-solid-svg-icons';
|
||||||
|
|
||||||
|
import Flash from './Flash';
|
||||||
|
import OperationsQueue from './OperationsQueue';
|
||||||
|
import TypeDeChamps from './components/TypeDeChamps';
|
||||||
|
|
||||||
|
library.add(
|
||||||
|
faArrowCircleDown,
|
||||||
|
faArrowDown,
|
||||||
|
faArrowsAltV,
|
||||||
|
faArrowUp,
|
||||||
|
faPlus,
|
||||||
|
faTrash
|
||||||
|
);
|
||||||
|
|
||||||
|
class TypesDeChampEditor extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
const defaultTypeDeChampAttributes = {
|
||||||
|
type_champ: 'text',
|
||||||
|
types_de_champ: [],
|
||||||
|
private: props.isAnnotation,
|
||||||
|
libelle: `${
|
||||||
|
props.isAnnotation ? 'Nouvelle annotation' : 'Nouveau champ'
|
||||||
|
} ${props.typeDeChampsTypes[0][0]}`
|
||||||
|
};
|
||||||
|
this.state = {
|
||||||
|
flash: new Flash(props.isAnnotation),
|
||||||
|
queue: new OperationsQueue(props.baseUrl),
|
||||||
|
defaultTypeDeChampAttributes,
|
||||||
|
typeDeChampsTypes: props.typeDeChampsTypes,
|
||||||
|
directUploadUrl: props.directUploadUrl,
|
||||||
|
isAnnotation: props.isAnnotation
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<TypeDeChamps state={this.state} typeDeChamps={this.props.typeDeChamps} />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TypesDeChampEditor.propTypes = {
|
||||||
|
baseUrl: PropTypes.string,
|
||||||
|
directUploadUrl: PropTypes.string,
|
||||||
|
isAnnotation: PropTypes.bool,
|
||||||
|
typeDeChamps: PropTypes.array,
|
||||||
|
typeDeChampsTypes: PropTypes.array
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TypesDeChampEditor;
|
|
@ -1,66 +1,3 @@
|
||||||
import React, { Component } from 'react';
|
import Loadable from '../Loadable';
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core';
|
|
||||||
import {
|
|
||||||
faArrowDown,
|
|
||||||
faArrowsAltV,
|
|
||||||
faArrowUp,
|
|
||||||
faArrowCircleDown,
|
|
||||||
faPlus,
|
|
||||||
faTrash
|
|
||||||
} from '@fortawesome/free-solid-svg-icons';
|
|
||||||
|
|
||||||
import Flash from './Flash';
|
export default Loadable(() => import('./TypesDeChampEditor'));
|
||||||
import OperationsQueue from './OperationsQueue';
|
|
||||||
import TypeDeChamps from './components/TypeDeChamps';
|
|
||||||
|
|
||||||
library.add(
|
|
||||||
faArrowDown,
|
|
||||||
faArrowsAltV,
|
|
||||||
faArrowUp,
|
|
||||||
faArrowCircleDown,
|
|
||||||
faPlus,
|
|
||||||
faTrash
|
|
||||||
);
|
|
||||||
|
|
||||||
class TypesDeChampEditor extends Component {
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
const defaultTypeDeChampAttributes = {
|
|
||||||
type_champ: 'text',
|
|
||||||
types_de_champ: [],
|
|
||||||
private: props.isAnnotation,
|
|
||||||
libelle: `${
|
|
||||||
props.isAnnotation ? 'Nouvelle annotation' : 'Nouveau champ'
|
|
||||||
} ${props.typeDeChampsTypes[0][0]}`
|
|
||||||
};
|
|
||||||
this.state = {
|
|
||||||
flash: new Flash(props.isAnnotation),
|
|
||||||
queue: new OperationsQueue(props.baseUrl),
|
|
||||||
defaultTypeDeChampAttributes,
|
|
||||||
typeDeChampsTypes: props.typeDeChampsTypes,
|
|
||||||
directUploadUrl: props.directUploadUrl,
|
|
||||||
isAnnotation: props.isAnnotation
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<TypeDeChamps state={this.state} typeDeChamps={this.props.typeDeChamps} />
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TypesDeChampEditor.propTypes = {
|
|
||||||
baseUrl: PropTypes.string,
|
|
||||||
directUploadUrl: PropTypes.string,
|
|
||||||
isAnnotation: PropTypes.bool,
|
|
||||||
typeDeChamps: PropTypes.array,
|
|
||||||
typeDeChampsTypes: PropTypes.array
|
|
||||||
};
|
|
||||||
|
|
||||||
export function createReactUJSElement(props) {
|
|
||||||
return React.createElement(TypesDeChampEditor, props);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default TypesDeChampEditor;
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ const autosaveController = new AutosaveController();
|
||||||
// Whenever a 'change' event is triggered on one of the form inputs, try to autosave.
|
// Whenever a 'change' event is triggered on one of the form inputs, try to autosave.
|
||||||
|
|
||||||
const formSelector = 'form#dossier-edit-form.autosave-enabled';
|
const formSelector = 'form#dossier-edit-form.autosave-enabled';
|
||||||
const formInputsSelector = `${formSelector} input:not([type=input]), ${formSelector} select, ${formSelector} textarea`;
|
const formInputsSelector = `${formSelector} input:not([type=file]), ${formSelector} select, ${formSelector} textarea`;
|
||||||
|
|
||||||
delegate(
|
delegate(
|
||||||
'change',
|
'change',
|
||||||
|
|
|
@ -6,9 +6,7 @@ import '@rails/actiontext';
|
||||||
import 'whatwg-fetch'; // window.fetch polyfill
|
import 'whatwg-fetch'; // window.fetch polyfill
|
||||||
import Chartkick from 'chartkick';
|
import Chartkick from 'chartkick';
|
||||||
import Highcharts from 'highcharts';
|
import Highcharts from 'highcharts';
|
||||||
|
import ReactRailsUJS from 'react_ujs';
|
||||||
import ReactUJS from '../shared/react-ujs';
|
|
||||||
import reactComponents from '../shared/react-components';
|
|
||||||
|
|
||||||
import '../shared/page-update-event';
|
import '../shared/page-update-event';
|
||||||
import '../shared/activestorage/ujs';
|
import '../shared/activestorage/ujs';
|
||||||
|
@ -61,8 +59,18 @@ Rails.start();
|
||||||
Turbolinks.start();
|
Turbolinks.start();
|
||||||
ActiveStorage.start();
|
ActiveStorage.start();
|
||||||
|
|
||||||
const loader = new ReactUJS(reactComponents);
|
// If Turbolinks is imported via Webpacker (and thus not available globally),
|
||||||
loader.start();
|
// ReactRailsUJS will be unable to locate it.
|
||||||
|
// https://github.com/reactjs/react-rails#event-handling
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-undef
|
||||||
|
ReactRailsUJS.useContext(require.context('components', true));
|
||||||
|
// Add Turbolinks to the global namespace:
|
||||||
|
window.Turbolinks = Turbolinks;
|
||||||
|
// Remove previous event handlers and add new ones:
|
||||||
|
ReactRailsUJS.detectEvents();
|
||||||
|
// (Optional) Clean up global namespace:
|
||||||
|
delete window.Turbolinks;
|
||||||
|
|
||||||
// Expose globals
|
// Expose globals
|
||||||
window.DS = window.DS || DS;
|
window.DS = window.DS || DS;
|
||||||
|
|
8
app/javascript/shared/react-components.js
vendored
8
app/javascript/shared/react-components.js
vendored
|
@ -1,8 +0,0 @@
|
||||||
export default function reactComponents(className) {
|
|
||||||
switch (className) {
|
|
||||||
case 'TypesDeChampEditor':
|
|
||||||
return import('components/TypesDeChampEditor').then(
|
|
||||||
mod => mod.createReactUJSElement
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
61
app/javascript/shared/react-ujs.js
vendored
61
app/javascript/shared/react-ujs.js
vendored
|
@ -1,61 +0,0 @@
|
||||||
import ReactDOM from 'react-dom';
|
|
||||||
|
|
||||||
// This attribute holds the name of component which should be mounted
|
|
||||||
// example: `data-react-class="MyApp.Items.EditForm"`
|
|
||||||
const CLASS_NAME_ATTR = 'data-react-class';
|
|
||||||
|
|
||||||
// This attribute holds JSON stringified props for initializing the component
|
|
||||||
// example: `data-react-props="{\"item\": { \"id\": 1, \"name\": \"My Item\"} }"`
|
|
||||||
const PROPS_ATTR = 'data-react-props';
|
|
||||||
|
|
||||||
// This attribute holds which method to use between: ReactDOM.hydrate, ReactDOM.render
|
|
||||||
const RENDER_ATTR = 'data-hydrate';
|
|
||||||
|
|
||||||
function findDOMNodes() {
|
|
||||||
return document.querySelectorAll(`[${CLASS_NAME_ATTR}]`);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class ReactUJS {
|
|
||||||
constructor(loadComponent) {
|
|
||||||
this.loadComponent = loadComponent;
|
|
||||||
}
|
|
||||||
|
|
||||||
async mountComponents() {
|
|
||||||
const nodes = findDOMNodes();
|
|
||||||
|
|
||||||
for (let node of nodes) {
|
|
||||||
const className = node.getAttribute(CLASS_NAME_ATTR);
|
|
||||||
const createReactUJSElement = await this.loadComponent(className).catch(
|
|
||||||
() => null
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!createReactUJSElement) {
|
|
||||||
const message = "Cannot find component: '" + className + "'";
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.error(
|
|
||||||
'%c[react-rails] %c' + message + ' for element',
|
|
||||||
'font-weight: bold',
|
|
||||||
'',
|
|
||||||
node
|
|
||||||
);
|
|
||||||
throw new Error(
|
|
||||||
message + '. Make sure your component is available to render.'
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
const propsJson = node.getAttribute(PROPS_ATTR);
|
|
||||||
const props = propsJson && JSON.parse(propsJson);
|
|
||||||
const hydrate = node.getAttribute(RENDER_ATTR);
|
|
||||||
|
|
||||||
if (hydrate && typeof ReactDOM.hydrate === 'function') {
|
|
||||||
ReactDOM.hydrate(createReactUJSElement(props), node);
|
|
||||||
} else {
|
|
||||||
ReactDOM.render(createReactUJSElement(props), node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
start() {
|
|
||||||
addEventListener('ds:page:update', () => this.mountComponents());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -8,7 +8,7 @@ class AutoArchiveProcedureJob < ApplicationJob
|
||||||
.state_en_construction
|
.state_en_construction
|
||||||
.find_each(&:passer_automatiquement_en_instruction!)
|
.find_each(&:passer_automatiquement_en_instruction!)
|
||||||
|
|
||||||
procedure.archive!
|
procedure.close!
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -20,7 +20,7 @@ class FindDubiousProceduresJob < ApplicationJob
|
||||||
.joins(:procedure)
|
.joins(:procedure)
|
||||||
.where("unaccent(types_de_champ.libelle) ~* unaccent(?)", forbidden_regexp)
|
.where("unaccent(types_de_champ.libelle) ~* unaccent(?)", forbidden_regexp)
|
||||||
.where(type_champ: [TypeDeChamp.type_champs.fetch(:text), TypeDeChamp.type_champs.fetch(:textarea)])
|
.where(type_champ: [TypeDeChamp.type_champs.fetch(:text), TypeDeChamp.type_champs.fetch(:textarea)])
|
||||||
.where(procedures: { archived_at: nil, whitelisted_at: nil })
|
.where(procedures: { closed_at: nil, whitelisted_at: nil })
|
||||||
|
|
||||||
dubious_procedures_and_tdcs = forbidden_tdcs
|
dubious_procedures_and_tdcs = forbidden_tdcs
|
||||||
.group_by(&:procedure_id)
|
.group_by(&:procedure_id)
|
||||||
|
|
|
@ -14,7 +14,7 @@ class Administrateur < ApplicationRecord
|
||||||
before_validation -> { sanitize_email(:email) }
|
before_validation -> { sanitize_email(:email) }
|
||||||
|
|
||||||
scope :inactive, -> { joins(:user).where(users: { last_sign_in_at: nil }) }
|
scope :inactive, -> { joins(:user).where(users: { last_sign_in_at: nil }) }
|
||||||
scope :with_publiees_ou_archivees, -> { joins(:procedures).where(procedures: { aasm_state: [:publiee, :archivee] }) }
|
scope :with_publiees_ou_closes, -> { joins(:procedures).where(procedures: { aasm_state: [:publiee, :archivee, :close] }) }
|
||||||
|
|
||||||
# validate :password_complexity, if: Proc.new { |a| Devise.password_length.include?(a.password.try(:size)) }
|
# validate :password_complexity, if: Proc.new { |a| Devise.password_length.include?(a.password.try(:size)) }
|
||||||
|
|
||||||
|
|
|
@ -257,7 +257,7 @@ class Dossier < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def can_transition_to_en_construction?
|
def can_transition_to_en_construction?
|
||||||
!procedure.archivee? && brouillon?
|
!procedure.close? && brouillon?
|
||||||
end
|
end
|
||||||
|
|
||||||
def can_be_updated_by_user?
|
def can_be_updated_by_user?
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
require Rails.root.join('lib', 'percentile')
|
require Rails.root.join('lib', 'percentile')
|
||||||
|
|
||||||
class Procedure < ApplicationRecord
|
class Procedure < ApplicationRecord
|
||||||
self.ignored_columns = ['logo', 'logo_secure_token']
|
self.ignored_columns = ['logo', 'logo_secure_token', 'test_started_at']
|
||||||
|
|
||||||
include ProcedureStatsConcern
|
include ProcedureStatsConcern
|
||||||
|
|
||||||
|
@ -46,8 +46,8 @@ class Procedure < ApplicationRecord
|
||||||
default_scope { where(hidden_at: nil) }
|
default_scope { where(hidden_at: nil) }
|
||||||
scope :brouillons, -> { where(aasm_state: :brouillon) }
|
scope :brouillons, -> { where(aasm_state: :brouillon) }
|
||||||
scope :publiees, -> { where(aasm_state: :publiee) }
|
scope :publiees, -> { where(aasm_state: :publiee) }
|
||||||
scope :archivees, -> { where(aasm_state: :archivee) }
|
scope :closes, -> { where(aasm_state: [:archivee, :close]) }
|
||||||
scope :publiees_ou_archivees, -> { where(aasm_state: [:publiee, :archivee]) }
|
scope :publiees_ou_closes, -> { where(aasm_state: [:publiee, :close, :archivee]) }
|
||||||
scope :by_libelle, -> { order(libelle: :asc) }
|
scope :by_libelle, -> { order(libelle: :asc) }
|
||||||
scope :created_during, -> (range) { where(created_at: range) }
|
scope :created_during, -> (range) { where(created_at: range) }
|
||||||
scope :cloned_from_library, -> { where(cloned_from_library: true) }
|
scope :cloned_from_library, -> { where(cloned_from_library: true) }
|
||||||
|
@ -77,7 +77,7 @@ class Procedure < ApplicationRecord
|
||||||
validates :lien_site_web, presence: true, if: :publiee?
|
validates :lien_site_web, presence: true, if: :publiee?
|
||||||
validate :validate_for_publication, on: :publication
|
validate :validate_for_publication, on: :publication
|
||||||
validate :check_juridique
|
validate :check_juridique
|
||||||
validates :path, presence: true, format: { with: /\A[a-z0-9_\-]{3,50}\z/ }, uniqueness: { scope: [:path, :archived_at, :hidden_at], case_sensitive: false }
|
validates :path, presence: true, format: { with: /\A[a-z0-9_\-]{3,50}\z/ }, uniqueness: { scope: [:path, :closed_at, :archived_at, :hidden_at], case_sensitive: false }
|
||||||
# FIXME: remove duree_conservation_required flag once all procedures are converted to the new style
|
# FIXME: remove duree_conservation_required flag once all procedures are converted to the new style
|
||||||
validates :duree_conservation_dossiers_dans_ds, allow_nil: false, numericality: { only_integer: true, greater_than_or_equal_to: 1, less_than_or_equal_to: MAX_DUREE_CONSERVATION }, if: :durees_conservation_required
|
validates :duree_conservation_dossiers_dans_ds, allow_nil: false, numericality: { only_integer: true, greater_than_or_equal_to: 1, less_than_or_equal_to: MAX_DUREE_CONSERVATION }, if: :durees_conservation_required
|
||||||
validates :duree_conservation_dossiers_hors_ds, allow_nil: false, numericality: { only_integer: true, greater_than_or_equal_to: 0 }, if: :durees_conservation_required
|
validates :duree_conservation_dossiers_hors_ds, allow_nil: false, numericality: { only_integer: true, greater_than_or_equal_to: 0 }, if: :durees_conservation_required
|
||||||
|
@ -95,26 +95,22 @@ class Procedure < ApplicationRecord
|
||||||
aasm whiny_persistence: true do
|
aasm whiny_persistence: true do
|
||||||
state :brouillon, initial: true
|
state :brouillon, initial: true
|
||||||
state :publiee
|
state :publiee
|
||||||
state :archivee
|
state :close
|
||||||
state :hidden
|
state :hidden
|
||||||
|
|
||||||
event :publish, before: :before_publish, after: :after_publish do
|
event :publish, before: :before_publish, after: :after_publish do
|
||||||
transitions from: :brouillon, to: :publiee
|
transitions from: :brouillon, to: :publiee
|
||||||
transitions from: :archivee, to: :publiee
|
transitions from: :close, to: :publiee
|
||||||
end
|
end
|
||||||
|
|
||||||
event :archive, after: :after_archive do
|
event :close, after: :after_close do
|
||||||
transitions from: :publiee, to: :archivee
|
transitions from: :publiee, to: :close
|
||||||
end
|
end
|
||||||
|
|
||||||
event :hide, after: :after_hide do
|
event :hide, after: :after_hide do
|
||||||
transitions from: :brouillon, to: :hidden
|
transitions from: :brouillon, to: :hidden
|
||||||
transitions from: :publiee, to: :hidden
|
transitions from: :publiee, to: :hidden
|
||||||
transitions from: :archivee, to: :hidden
|
transitions from: :close, to: :hidden
|
||||||
end
|
|
||||||
|
|
||||||
event :draft, after: :after_draft do
|
|
||||||
transitions from: :publiee, to: :brouillon
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -126,7 +122,7 @@ class Procedure < ApplicationRecord
|
||||||
|
|
||||||
other_procedure = other_procedure_with_path(path)
|
other_procedure = other_procedure_with_path(path)
|
||||||
if other_procedure.present? && administrateur.owns?(other_procedure)
|
if other_procedure.present? && administrateur.owns?(other_procedure)
|
||||||
other_procedure.archive!
|
other_procedure.close!
|
||||||
end
|
end
|
||||||
|
|
||||||
publish!
|
publish!
|
||||||
|
@ -231,9 +227,10 @@ class Procedure < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_for_publication
|
def validate_for_publication
|
||||||
old_attributes = self.slice(:aasm_state, :archived_at)
|
old_attributes = self.slice(:aasm_state, :archived_at, :closed_at)
|
||||||
self.aasm_state = :publiee
|
self.aasm_state = :publiee
|
||||||
self.archived_at = nil
|
self.archived_at = nil
|
||||||
|
self.closed_at = nil
|
||||||
|
|
||||||
is_valid = validate
|
is_valid = validate
|
||||||
|
|
||||||
|
@ -276,16 +273,24 @@ class Procedure < ApplicationRecord
|
||||||
update(csv_export_queued: false, xlsx_export_queued: false, ods_export_queued: false)
|
update(csv_export_queued: false, xlsx_export_queued: false, ods_export_queued: false)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def closed_at
|
||||||
|
read_attribute(:closed_at).presence || archived_at
|
||||||
|
end
|
||||||
|
|
||||||
|
def close?
|
||||||
|
aasm_state == 'close' || aasm_state == 'archivee'
|
||||||
|
end
|
||||||
|
|
||||||
def locked?
|
def locked?
|
||||||
publiee_ou_archivee?
|
publiee_ou_close?
|
||||||
end
|
end
|
||||||
|
|
||||||
def accepts_new_dossiers?
|
def accepts_new_dossiers?
|
||||||
!archivee?
|
!close?
|
||||||
end
|
end
|
||||||
|
|
||||||
def publiee_ou_archivee?
|
def publiee_ou_close?
|
||||||
publiee? || archivee?
|
publiee? || close?
|
||||||
end
|
end
|
||||||
|
|
||||||
def expose_legacy_carto_api?
|
def expose_legacy_carto_api?
|
||||||
|
@ -366,8 +371,8 @@ class Procedure < ApplicationRecord
|
||||||
}, &method(:clone_attachments))
|
}, &method(:clone_attachments))
|
||||||
procedure.path = SecureRandom.uuid
|
procedure.path = SecureRandom.uuid
|
||||||
procedure.aasm_state = :brouillon
|
procedure.aasm_state = :brouillon
|
||||||
procedure.test_started_at = nil
|
|
||||||
procedure.archived_at = nil
|
procedure.archived_at = nil
|
||||||
|
procedure.closed_at = nil
|
||||||
procedure.published_at = nil
|
procedure.published_at = nil
|
||||||
procedure.lien_notice = nil
|
procedure.lien_notice = nil
|
||||||
|
|
||||||
|
@ -604,15 +609,16 @@ class Procedure < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def before_publish
|
def before_publish
|
||||||
update!(archived_at: nil)
|
update!(archived_at: nil, closed_at: nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
def after_publish
|
def after_publish
|
||||||
update!(published_at: Time.zone.now)
|
update!(published_at: Time.zone.now)
|
||||||
end
|
end
|
||||||
|
|
||||||
def after_archive
|
def after_close
|
||||||
update!(archived_at: Time.zone.now)
|
now = Time.zone.now
|
||||||
|
update!(archived_at: now, closed_at: now)
|
||||||
purge_export_files
|
purge_export_files
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -623,10 +629,6 @@ class Procedure < ApplicationRecord
|
||||||
purge_export_files
|
purge_export_files
|
||||||
end
|
end
|
||||||
|
|
||||||
def after_draft
|
|
||||||
update!(published_at: nil)
|
|
||||||
end
|
|
||||||
|
|
||||||
def update_juridique_required
|
def update_juridique_required
|
||||||
self.juridique_required ||= (cadre_juridique.present? || deliberation.attached?)
|
self.juridique_required ||= (cadre_juridique.present? || deliberation.attached?)
|
||||||
true
|
true
|
||||||
|
|
|
@ -20,7 +20,7 @@ class ProcedureSerializer < ActiveModel::Serializer
|
||||||
belongs_to :service, serializer: ServiceSerializer
|
belongs_to :service, serializer: ServiceSerializer
|
||||||
|
|
||||||
def archived_at
|
def archived_at
|
||||||
object.archived_at&.in_time_zone('UTC')
|
object.closed_at&.in_time_zone('UTC')
|
||||||
end
|
end
|
||||||
|
|
||||||
def link
|
def link
|
||||||
|
@ -32,7 +32,8 @@ class ProcedureSerializer < ActiveModel::Serializer
|
||||||
end
|
end
|
||||||
|
|
||||||
def state
|
def state
|
||||||
object.aasm_state
|
state = object.aasm_state
|
||||||
|
state == 'close' ? 'archivee' : state
|
||||||
end
|
end
|
||||||
|
|
||||||
def geographic_information
|
def geographic_information
|
||||||
|
|
|
@ -35,7 +35,7 @@ class AdministrateurUsageStatisticsService
|
||||||
nb_instructeurs: nb_instructeurs_by_administrateur_id[administrateur.id],
|
nb_instructeurs: nb_instructeurs_by_administrateur_id[administrateur.id],
|
||||||
|
|
||||||
ds_nb_demarches_actives: nb_demarches_by_administrateur_id_and_state[[administrateur.id, "publiee"]],
|
ds_nb_demarches_actives: nb_demarches_by_administrateur_id_and_state[[administrateur.id, "publiee"]],
|
||||||
ds_nb_demarches_archives: nb_demarches_by_administrateur_id_and_state[[administrateur.id, "archivee"]],
|
ds_nb_demarches_archives: nb_demarches_by_administrateur_id_and_state[[administrateur.id, "close"]],
|
||||||
ds_nb_demarches_brouillons: nb_demarches_by_administrateur_id_and_state[[administrateur.id, "brouillon"]],
|
ds_nb_demarches_brouillons: nb_demarches_by_administrateur_id_and_state[[administrateur.id, "brouillon"]],
|
||||||
|
|
||||||
nb_demarches_test: nb_dossiers_by_procedure_id
|
nb_demarches_test: nb_dossiers_by_procedure_id
|
||||||
|
|
|
@ -19,13 +19,13 @@
|
||||||
%td.col-xs-6= link_to(procedure.libelle, admin_procedure_href)
|
%td.col-xs-6= link_to(procedure.libelle, admin_procedure_href)
|
||||||
- if procedure.publiee?
|
- if procedure.publiee?
|
||||||
%td.procedure-lien= link_to(procedure_lien(procedure), procedure_lien(procedure))
|
%td.procedure-lien= link_to(procedure_lien(procedure), procedure_lien(procedure))
|
||||||
- if procedure.publiee_ou_archivee?
|
- if procedure.publiee_ou_close?
|
||||||
%td= link_to(procedure.published_at.present? ? try_format_datetime(procedure.published_at) : "", admin_procedure_href)
|
%td= link_to(procedure.published_at.present? ? try_format_datetime(procedure.published_at) : "", admin_procedure_href)
|
||||||
- else
|
- else
|
||||||
%td= link_to(try_format_datetime(procedure.created_at), admin_procedure_href)
|
%td= link_to(try_format_datetime(procedure.created_at), admin_procedure_href)
|
||||||
%td
|
%td
|
||||||
= link_to('Cloner', admin_procedure_clone_path(procedure.id), data: { method: :put }, class: 'btn-sm btn-primary clone-btn')
|
= link_to('Cloner', admin_procedure_clone_path(procedure.id), data: { method: :put }, class: 'btn-sm btn-primary clone-btn')
|
||||||
- if !procedure.publiee_ou_archivee?
|
- if !procedure.publiee_ou_close?
|
||||||
= link_to('X', url_for(controller: 'admin/procedures', action: :destroy, id: procedure.id), data: { method: :delete, confirm: "Confirmez-vous la suppression de la démarche ? \n\n Attention : toute suppression est définitive et s’appliquera aux éventuels autres administrateurs de cette démarche !" }, class: 'btn-sm btn-danger')
|
= link_to('X', url_for(controller: 'admin/procedures', action: :destroy, id: procedure.id), data: { method: :delete, confirm: "Confirmez-vous la suppression de la démarche ? \n\n Attention : toute suppression est définitive et s’appliquera aux éventuels autres administrateurs de cette démarche !" }, class: 'btn-sm btn-danger')
|
||||||
|
|
||||||
= smart_listing.paginate
|
= smart_listing.paginate
|
||||||
|
|
|
@ -13,5 +13,5 @@
|
||||||
%li{ class: @archived_class }
|
%li{ class: @archived_class }
|
||||||
%a{ :href => "#{url_for :admin_procedures_archived}" }
|
%a{ :href => "#{url_for :admin_procedures_archived}" }
|
||||||
%h5{ style: 'color: black;' }
|
%h5{ style: 'color: black;' }
|
||||||
Archivées
|
Closes
|
||||||
%br
|
%br
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
%i.fa.fa-exchange
|
%i.fa.fa-exchange
|
||||||
Envoyer une copie
|
Envoyer une copie
|
||||||
|
|
||||||
- if @procedure.archivee?
|
- if @procedure.close?
|
||||||
%a.btn.btn-default#reopen-procedure{ data: { target: '#publish-modal', toggle: :modal }, type: 'button', style: 'float: right; margin-top: 10px; margin-right: 10px;' }
|
%a.btn.btn-default#reopen-procedure{ data: { target: '#publish-modal', toggle: :modal }, type: 'button', style: 'float: right; margin-top: 10px; margin-right: 10px;' }
|
||||||
%i.fa.fa-rocket
|
%i.fa.fa-rocket
|
||||||
Réactiver
|
Réactiver
|
||||||
|
@ -49,8 +49,8 @@
|
||||||
- else
|
- else
|
||||||
Publication
|
Publication
|
||||||
%div{ style: 'margin-top: 30px;' }
|
%div{ style: 'margin-top: 30px;' }
|
||||||
- if @procedure.archivee?
|
- if @procedure.close?
|
||||||
Cette démarche est <strong>archivée</strong> et n’est donc plus accessible par le public.
|
Cette démarche est <strong>close</strong> et n’est donc plus accessible par le public.
|
||||||
- elsif @procedure.publiee?
|
- elsif @procedure.publiee?
|
||||||
Cette démarche est <strong>publiée</strong>, certains éléments ne peuvent plus être modifiés.
|
Cette démarche est <strong>publiée</strong>, certains éléments ne peuvent plus être modifiés.
|
||||||
Pour y accéder vous pouvez utiliser le lien :
|
Pour y accéder vous pouvez utiliser le lien :
|
||||||
|
|
|
@ -61,6 +61,6 @@
|
||||||
.stats-legend
|
.stats-legend
|
||||||
= t('pluralize.archived', count: archived_count)
|
= t('pluralize.archived', count: archived_count)
|
||||||
|
|
||||||
- if p.archivee?
|
- if p.close?
|
||||||
.procedure-status
|
.procedure-status
|
||||||
%span.label Archivée
|
%span.label Close
|
||||||
|
|
|
@ -3,14 +3,17 @@
|
||||||
- dossier = controller.try(:dossier_for_help)
|
- dossier = controller.try(:dossier_for_help)
|
||||||
- procedure = controller.try(:procedure_for_help)
|
- procedure = controller.try(:procedure_for_help)
|
||||||
|
|
||||||
%header.new-header{ class: current_page?(root_path) ? nil : "new-header-with-border" }
|
%header.new-header{ class: current_page?(root_path) ? nil : "new-header-with-border", role: 'banner' }
|
||||||
.header-inner-content
|
.header-inner-content
|
||||||
|
|
||||||
.flex.align-center
|
.flex.align-center
|
||||||
- if params[:controller] == 'users/commencer'
|
- if params[:controller] == 'users/commencer'
|
||||||
= link_to 'Revenir en arrière', url_for(:back), class: "button", title: "Revenir sur le site de mon administration"
|
= link_to 'Revenir en arrière', url_for(:back), class: "button", title: "Revenir sur le site de mon administration"
|
||||||
- else
|
- else
|
||||||
= link_to '', root_path_for_profile(nav_bar_profile), class: "header-logo", title: "Revenir à l’accueil"
|
= link_to root_path_for_profile(nav_bar_profile), class: 'header-logo', title: "Aller à la page d'accueil de demarches-simplifiees.fr" do
|
||||||
|
= image_tag 'marianne.svg', alt: '', width: 65
|
||||||
|
%span.big.site-title> demarches-simplifiees.fr
|
||||||
|
%span.small.site-title> d-s.fr
|
||||||
|
|
||||||
- if nav_bar_profile == :instructeur && instructeur_signed_in?
|
- if nav_bar_profile == :instructeur && instructeur_signed_in?
|
||||||
- current_url = request.path_info
|
- current_url = request.path_info
|
||||||
|
@ -34,7 +37,7 @@
|
||||||
%ul.header-right-content
|
%ul.header-right-content
|
||||||
- if nav_bar_profile == :instructeur && instructeur_signed_in?
|
- if nav_bar_profile == :instructeur && instructeur_signed_in?
|
||||||
%li
|
%li
|
||||||
.header-search
|
.header-search{ role: 'search' }
|
||||||
= form_tag instructeur_recherche_path, method: :get, class: "form" do
|
= form_tag instructeur_recherche_path, method: :get, class: "form" do
|
||||||
= text_field_tag "q", "#{@search_terms if @search_terms.present?}", placeholder: "Rechercher un dossier"
|
= text_field_tag "q", "#{@search_terms if @search_terms.present?}", placeholder: "Rechercher un dossier"
|
||||||
%button{ title: "Rechercher" }
|
%button{ title: "Rechercher" }
|
||||||
|
@ -42,7 +45,7 @@
|
||||||
|
|
||||||
- if nav_bar_profile == :user && user_signed_in? && current_user.dossiers.count > 2
|
- if nav_bar_profile == :user && user_signed_in? && current_user.dossiers.count > 2
|
||||||
%li
|
%li
|
||||||
.header-search
|
.header-search{ role: 'search' }
|
||||||
= form_tag recherche_dossiers_path, method: :post, class: "form" do
|
= form_tag recherche_dossiers_path, method: :post, class: "form" do
|
||||||
= text_field_tag :dossier_id, "", placeholder: "Numéro de dossier"
|
= text_field_tag :dossier_id, "", placeholder: "Numéro de dossier"
|
||||||
%button{ title: "Rechercher" }
|
%button{ title: "Rechercher" }
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
- if !browser.modern?
|
- if !browser.modern?
|
||||||
#outdated-browser-banner
|
#outdated-browser-banner
|
||||||
.container
|
.container
|
||||||
Attention, votre navigateur (#{browser.name} #{browser.version}) est trop ancien pour utiliser demarches-simplifiees.fr : certaines parties du site ne fonctionneront pas correctement. Nous vous recommendons fortement de
|
Attention, votre navigateur (#{browser.name} #{browser.version}) est trop ancien pour utiliser demarches-simplifiees.fr : certaines parties du site ne fonctionneront pas correctement. Nous vous recommandons fortement de
|
||||||
%a{ href: "https://browser-update.org/fr/update.html", target: "_blank", rel: "noopener" }mettre à jour votre navigateur
|
%a{ href: "https://browser-update.org/fr/update.html", target: "_blank", rel: "noopener" }mettre à jour votre navigateur
|
||||||
%span<>
|
%span<>
|
||||||
\.
|
\.
|
||||||
|
|
|
@ -23,9 +23,9 @@
|
||||||
|
|
||||||
%a#archived-procedures{ :href => "#{url_for :admin_procedures_archived}" }
|
%a#archived-procedures{ :href => "#{url_for :admin_procedures_archived}" }
|
||||||
.procedure-list-element{ class: @archived_class }
|
.procedure-list-element{ class: @archived_class }
|
||||||
Archivées
|
Closes
|
||||||
.badge.progress-bar-purple
|
.badge.progress-bar-purple
|
||||||
= current_administrateur.procedures.archivees.count
|
= current_administrateur.procedures.closes.count
|
||||||
|
|
||||||
.split-hr-left
|
.split-hr-left
|
||||||
= render partial: 'layouts/switch_devise_profile_module'
|
= render partial: 'layouts/switch_devise_profile_module'
|
||||||
|
|
|
@ -39,10 +39,6 @@ as well as a link to its edit page.
|
||||||
<%= link_to 'whitelister', whitelist_manager_procedure_path(procedure), method: :post, class: 'button' %>
|
<%= link_to 'whitelister', whitelist_manager_procedure_path(procedure), method: :post, class: 'button' %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<% if procedure.publiee? && procedure.dossiers.empty? %>
|
|
||||||
<%= link_to 'repasser en test', draft_manager_procedure_path(procedure), method: :post, class: 'button' %>
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<% if !procedure.hidden? %>
|
<% if !procedure.hidden? %>
|
||||||
<%= link_to 'supprimer la démarche', hide_manager_procedure_path(procedure), method: :post, class: 'button', data: { confirm: "Confirmez-vous la suppression de la démarche ?" } %>
|
<%= link_to 'supprimer la démarche', hide_manager_procedure_path(procedure), method: :post, class: 'button', data: { confirm: "Confirmez-vous la suppression de la démarche ?" } %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
%footer.landing-footer
|
%footer.landing-footer{ role: 'contentinfo' }
|
||||||
.container
|
.container
|
||||||
%ul.footer-columns
|
%ul.footer-columns
|
||||||
|
|
||||||
|
|
|
@ -141,7 +141,7 @@
|
||||||
%ul.numbers
|
%ul.numbers
|
||||||
%li.number
|
%li.number
|
||||||
.number-value
|
.number-value
|
||||||
= number_with_delimiter(Administrateur.with_publiees_ou_archivees.uniq.count, :locale => :fr)
|
= number_with_delimiter(Administrateur.with_publiees_ou_closes.uniq.count, :locale => :fr)
|
||||||
.number-label<
|
.number-label<
|
||||||
administrations
|
administrations
|
||||||
%br<>
|
%br<>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
.container
|
.container
|
||||||
.hero-wrapper
|
.hero-wrapper
|
||||||
.hero-text
|
.hero-text
|
||||||
%p.hero-tagline
|
%h1.hero-tagline
|
||||||
%em.hero-tagline-em Effectuer
|
%em.hero-tagline-em Effectuer
|
||||||
%br<>
|
%br<>
|
||||||
%em.hero-tagline-em une démarche administrative
|
%em.hero-tagline-em une démarche administrative
|
||||||
|
@ -14,16 +14,16 @@
|
||||||
%em.hero-tagline-em en ligne
|
%em.hero-tagline-em en ligne
|
||||||
|
|
||||||
.hero-illustration
|
.hero-illustration
|
||||||
%img{ :src => image_url("landing/hero/dematerialiser.svg"), alt: "dématérialisez" }
|
%img{ :src => image_url("landing/hero/dematerialiser.svg"), alt: '' }
|
||||||
|
|
||||||
.landing-panel.usagers-panel
|
.landing-panel.usagers-panel
|
||||||
.container
|
.container
|
||||||
.role-panel-wrapper
|
.role-panel-wrapper
|
||||||
.role-panel-30.role-usagers-image
|
.role-panel-30.role-usagers-image
|
||||||
%img.role-image{ :src => image_url("landing/roles/usagers.svg"), alt: "usager" }
|
%img.role-image{ :src => image_url("landing/roles/usagers.svg"), alt: '' }
|
||||||
|
|
||||||
.role-panel-70
|
.role-panel-70
|
||||||
%h1.role-panel-title Vous souhaitez effectuer une demande auprès d'une administration ?
|
%h2.role-panel-title Vous souhaitez effectuer une demande auprès d'une administration ?
|
||||||
%p.role-panel-explanation Réalisez vos demandes en toute simplicité et retrouvez vos dossiers en ligne
|
%p.role-panel-explanation Réalisez vos demandes en toute simplicité et retrouvez vos dossiers en ligne
|
||||||
|
|
||||||
= link_to "Comment trouver ma démarche ?",
|
= link_to "Comment trouver ma démarche ?",
|
||||||
|
@ -43,7 +43,7 @@
|
||||||
%ul.numbers
|
%ul.numbers
|
||||||
%li.number
|
%li.number
|
||||||
.number-value
|
.number-value
|
||||||
= number_with_delimiter(Procedure.includes(:administrateurs).publiees_ou_archivees.flat_map(&:administrateurs).uniq.count, :locale => :fr)
|
= number_with_delimiter(Procedure.includes(:administrateurs).publiees_ou_closes.flat_map(&:administrateurs).uniq.count, :locale => :fr)
|
||||||
.number-label<
|
.number-label<
|
||||||
administrations
|
administrations
|
||||||
%br<>
|
%br<>
|
||||||
|
@ -67,7 +67,7 @@
|
||||||
.container
|
.container
|
||||||
.cta-panel-wrapper
|
.cta-panel-wrapper
|
||||||
%div
|
%div
|
||||||
%h1.cta-panel-title Une question, un problème ?
|
%h2.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 Notre équipe est disponible pour vous renseigner et vous aider
|
||||||
%div
|
%div
|
||||||
= contact_link "Contactez-nous",
|
= contact_link "Contactez-nous",
|
||||||
|
@ -80,7 +80,7 @@
|
||||||
.container
|
.container
|
||||||
.cta-panel-wrapper
|
.cta-panel-wrapper
|
||||||
%div
|
%div
|
||||||
%h1.cta-panel-title Administration : vous voulez dématerialiser ?
|
%h2.cta-panel-title Administration : vous voulez dématerialiser ?
|
||||||
%p.cta-panel-explanation Proposez à vos usagers de remplir leurs dossiers en ligne
|
%p.cta-panel-explanation Proposez à vos usagers de remplir leurs dossiers en ligne
|
||||||
%div
|
%div
|
||||||
= link_to "Découvrez notre outil",
|
= link_to "Découvrez notre outil",
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
.card.featured
|
.card.featured
|
||||||
.card-title
|
.card-title
|
||||||
Le dépôt de dossier est fermé
|
Le dépôt de dossier est fermé
|
||||||
- if dossier.procedure.archived_at.present?
|
- if dossier.procedure.closed_at.present?
|
||||||
Il n'est plus possible de déposer de dossier pour cette démarche en ligne depuis le #{try_format_date(dossier.procedure.archived_at)}.
|
Il n'est plus possible de déposer de dossier pour cette démarche en ligne depuis le #{try_format_date(dossier.procedure.closed_at)}.
|
||||||
- else
|
- else
|
||||||
Il n'est plus possible de déposer de dossier pour cette démarche en ligne.
|
Il n'est plus possible de déposer de dossier pour cette démarche en ligne.
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
required: champ.mandatory?,
|
required: champ.mandatory?,
|
||||||
pattern: "[0-9]{14}",
|
pattern: "[0-9]{14}",
|
||||||
title: "Le numéro de SIRET doit comporter exactement 14 chiffres"
|
title: "Le numéro de SIRET doit comporter exactement 14 chiffres"
|
||||||
.spinner.right-spinner.hidden
|
.spinner.right.hidden
|
||||||
%div{ class: "siret-info-#{form.index}" }
|
%div{ class: "siret-info-#{form.index}" }
|
||||||
- if champ.etablissement.present?
|
- if champ.etablissement.present?
|
||||||
= render partial: 'shared/dossiers/editable_champs/etablissement_titre', locals: { etablissement: champ.etablissement }
|
= render partial: 'shared/dossiers/editable_champs/etablissement_titre', locals: { etablissement: champ.etablissement }
|
||||||
|
|
|
@ -186,7 +186,7 @@ fr:
|
||||||
etablissement_fail: 'Désolé, nous n’avons pas réussi à enregistrer l’établissement correspondant à ce numéro SIRET'
|
etablissement_fail: 'Désolé, nous n’avons pas réussi à enregistrer l’établissement correspondant à ce numéro SIRET'
|
||||||
france_connect:
|
france_connect:
|
||||||
connexion: "Erreur lors de la connexion à France Connect."
|
connexion: "Erreur lors de la connexion à France Connect."
|
||||||
procedure_archived: "Cette démarche en ligne a été fermée, il n'est plus possible de déposer de dossier."
|
procedure_archived: "Cette démarche en ligne a été close, il n'est plus possible de déposer de dossier."
|
||||||
procedure_not_draft: "Cette démarche n’est maintenant plus en brouillon."
|
procedure_not_draft: "Cette démarche n’est maintenant plus en brouillon."
|
||||||
cadastres_empty:
|
cadastres_empty:
|
||||||
one: "Aucune parcelle cadastrale sur la zone sélectionnée"
|
one: "Aucune parcelle cadastrale sur la zone sélectionnée"
|
||||||
|
|
|
@ -12,5 +12,5 @@ fr:
|
||||||
duree_conservation_dossiers_hors_ds: Durée de conservation des dossiers hors demarches-simplifiees.fr
|
duree_conservation_dossiers_hors_ds: Durée de conservation des dossiers hors demarches-simplifiees.fr
|
||||||
aasm_state/brouillon: Brouillon
|
aasm_state/brouillon: Brouillon
|
||||||
aasm_state/publiee: Publiée
|
aasm_state/publiee: Publiée
|
||||||
aasm_state/archivee: Archivée
|
aasm_state/close: Close
|
||||||
aasm_state/hidden: Suprimée
|
aasm_state/hidden: Suprimée
|
||||||
|
|
5
db/migrate/20191114084643_add_closed_at_to_procedures.rb
Normal file
5
db/migrate/20191114084643_add_closed_at_to_procedures.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
class AddClosedAtToProcedures < ActiveRecord::Migration[5.2]
|
||||||
|
def change
|
||||||
|
add_column :procedures, :closed_at, :datetime
|
||||||
|
end
|
||||||
|
end
|
|
@ -10,7 +10,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 2019_11_13_142816) do
|
ActiveRecord::Schema.define(version: 2019_11_14_113700) do
|
||||||
|
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "plpgsql"
|
enable_extension "plpgsql"
|
||||||
|
@ -488,6 +488,7 @@ ActiveRecord::Schema.define(version: 2019_11_13_142816) do
|
||||||
t.boolean "csv_export_queued"
|
t.boolean "csv_export_queued"
|
||||||
t.boolean "xlsx_export_queued"
|
t.boolean "xlsx_export_queued"
|
||||||
t.boolean "ods_export_queued"
|
t.boolean "ods_export_queued"
|
||||||
|
t.datetime "closed_at"
|
||||||
t.index ["declarative_with_state"], name: "index_procedures_on_declarative_with_state"
|
t.index ["declarative_with_state"], name: "index_procedures_on_declarative_with_state"
|
||||||
t.index ["hidden_at"], name: "index_procedures_on_hidden_at"
|
t.index ["hidden_at"], name: "index_procedures_on_hidden_at"
|
||||||
t.index ["parent_procedure_id"], name: "index_procedures_on_parent_procedure_id"
|
t.index ["parent_procedure_id"], name: "index_procedures_on_parent_procedure_id"
|
||||||
|
|
15
lib/tasks/deployment/20191114084623_archivee_to_close.rake
Normal file
15
lib/tasks/deployment/20191114084623_archivee_to_close.rake
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
namespace :after_party do
|
||||||
|
desc 'Deployment task: archivee_to_close'
|
||||||
|
task archivee_to_close: :environment do
|
||||||
|
puts "Running deploy task 'archivee_to_close'"
|
||||||
|
|
||||||
|
Procedure.where(aasm_state: :archivee).update_all(aasm_state: :close)
|
||||||
|
Procedure.where(aasm_state: :close, closed_at: nil).find_each do |procedure|
|
||||||
|
procedure.update_column(:closed_at, procedure.archived_at)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Update task as completed. If you remove the line below, the task will
|
||||||
|
# run with every deploy (or every time you call after_party:run).
|
||||||
|
AfterParty::TaskRecord.create version: '20191114084623'
|
||||||
|
end
|
||||||
|
end
|
|
@ -27,6 +27,7 @@
|
||||||
"react": "^16.11.0",
|
"react": "^16.11.0",
|
||||||
"react-dom": "^16.11.0",
|
"react-dom": "^16.11.0",
|
||||||
"react-intersection-observer": "^8.25.1",
|
"react-intersection-observer": "^8.25.1",
|
||||||
|
"react-loadable": "^5.5.0",
|
||||||
"react-scroll-to-component": "^1.0.2",
|
"react-scroll-to-component": "^1.0.2",
|
||||||
"react-sortable-hoc": "^1.10.1",
|
"react-sortable-hoc": "^1.10.1",
|
||||||
"react_ujs": "^2.6.0",
|
"react_ujs": "^2.6.0",
|
||||||
|
|
|
@ -96,9 +96,9 @@ describe Admin::ProceduresController, type: :controller do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'DELETE #destroy' do
|
describe 'DELETE #destroy' do
|
||||||
let(:procedure_draft) { create :procedure_with_dossiers, administrateur: admin, instructeurs: [admin.instructeur], published_at: nil, archived_at: nil }
|
let(:procedure_draft) { create :procedure_with_dossiers, administrateur: admin, instructeurs: [admin.instructeur], published_at: nil, closed_at: nil }
|
||||||
let(:procedure_published) { create :procedure_with_dossiers, administrateur: admin, instructeurs: [admin.instructeur], aasm_state: :publiee, published_at: Time.zone.now, archived_at: nil }
|
let(:procedure_published) { create :procedure_with_dossiers, administrateur: admin, instructeurs: [admin.instructeur], aasm_state: :publiee, published_at: Time.zone.now, closed_at: nil }
|
||||||
let(:procedure_archived) { create :procedure_with_dossiers, administrateur: admin, instructeurs: [admin.instructeur], aasm_state: :archivee, published_at: nil, archived_at: Time.zone.now }
|
let(:procedure_closed) { create :procedure_with_dossiers, administrateur: admin, instructeurs: [admin.instructeur], aasm_state: :close, published_at: nil, closed_at: Time.zone.now }
|
||||||
|
|
||||||
subject { delete :destroy, params: { id: procedure.id } }
|
subject { delete :destroy, params: { id: procedure.id } }
|
||||||
|
|
||||||
|
@ -129,8 +129,8 @@ describe Admin::ProceduresController, type: :controller do
|
||||||
it { expect(subject.status).to eq 401 }
|
it { expect(subject.status).to eq 401 }
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when procedure is archived' do
|
context 'when procedure is closed' do
|
||||||
let!(:procedure) { procedure_archived }
|
let!(:procedure) { procedure_closed }
|
||||||
|
|
||||||
it { expect { subject }.not_to change { Procedure.count } }
|
it { expect { subject }.not_to change { Procedure.count } }
|
||||||
it { expect { subject }.not_to change { Dossier.count } }
|
it { expect { subject }.not_to change { Dossier.count } }
|
||||||
|
@ -138,7 +138,7 @@ describe Admin::ProceduresController, type: :controller do
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when administrateur does not own the procedure" do
|
context "when administrateur does not own the procedure" do
|
||||||
let(:procedure_not_owned) { create :procedure, administrateur: create(:administrateur), published_at: nil, archived_at: nil }
|
let(:procedure_not_owned) { create :procedure, administrateur: create(:administrateur), published_at: nil, closed_at: nil }
|
||||||
|
|
||||||
subject { delete :destroy, params: { id: procedure_not_owned.id } }
|
subject { delete :destroy, params: { id: procedure_not_owned.id } }
|
||||||
|
|
||||||
|
@ -185,7 +185,7 @@ describe Admin::ProceduresController, type: :controller do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'archive previous procedure' do
|
it 'archive previous procedure' do
|
||||||
expect(procedure2.archivee?).to be_truthy
|
expect(procedure2.close?).to be_truthy
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -201,7 +201,7 @@ describe Admin::ProceduresController, type: :controller do
|
||||||
|
|
||||||
it 'previous procedure remains published' do
|
it 'previous procedure remains published' do
|
||||||
expect(procedure2.publiee?).to be_truthy
|
expect(procedure2.publiee?).to be_truthy
|
||||||
expect(procedure2.archivee?).to be_falsey
|
expect(procedure2.close?).to be_falsey
|
||||||
expect(procedure2.path).to match(/fake_path/)
|
expect(procedure2.path).to match(/fake_path/)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -260,9 +260,9 @@ describe Admin::ProceduresController, type: :controller do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when owner want archive procedure' do
|
context 'when owner want archive procedure' do
|
||||||
it { expect(procedure.archivee?).to be_truthy }
|
it { expect(procedure.close?).to be_truthy }
|
||||||
it { expect(response).to redirect_to :admin_procedures }
|
it { expect(response).to redirect_to :admin_procedures }
|
||||||
it { expect(flash[:notice]).to have_content 'Démarche archivée' }
|
it { expect(flash[:notice]).to have_content 'Démarche close' }
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when owner want to re-enable procedure' do
|
context 'when owner want to re-enable procedure' do
|
||||||
|
@ -351,16 +351,16 @@ describe Admin::ProceduresController, type: :controller do
|
||||||
describe 'selecting' do
|
describe 'selecting' do
|
||||||
let!(:large_draft_procedure) { create(:procedure_with_dossiers, dossiers_count: 2) }
|
let!(:large_draft_procedure) { create(:procedure_with_dossiers, dossiers_count: 2) }
|
||||||
let!(:large_published_procedure) { create(:procedure_with_dossiers, :published, dossiers_count: 2) }
|
let!(:large_published_procedure) { create(:procedure_with_dossiers, :published, dossiers_count: 2) }
|
||||||
let!(:large_archived_procedure) { create(:procedure_with_dossiers, :archived, dossiers_count: 2) }
|
let!(:large_closed_procedure) { create(:procedure_with_dossiers, :closed, dossiers_count: 2) }
|
||||||
let!(:small_archived_procedure) { create(:procedure_with_dossiers, :archived, dossiers_count: 1) }
|
let!(:small_closed_procedure) { create(:procedure_with_dossiers, :closed, dossiers_count: 1) }
|
||||||
|
|
||||||
it 'displays published and archived procedures' do
|
it 'displays published and closed procedures' do
|
||||||
expect(response_procedures).to include(large_published_procedure)
|
expect(response_procedures).to include(large_published_procedure)
|
||||||
expect(response_procedures).to include(large_archived_procedure)
|
expect(response_procedures).to include(large_closed_procedure)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'doesn’t display procedures without a significant number of dossiers' do
|
it 'doesn’t display procedures without a significant number of dossiers' do
|
||||||
expect(response_procedures).not_to include(small_archived_procedure)
|
expect(response_procedures).not_to include(small_closed_procedure)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'doesn’t display draft procedures' do
|
it 'doesn’t display draft procedures' do
|
||||||
|
|
|
@ -35,7 +35,7 @@ describe API::V1::ProceduresController, type: :controller do
|
||||||
it { expect(subject[:description]).to eq(procedure.description) }
|
it { expect(subject[:description]).to eq(procedure.description) }
|
||||||
it { expect(subject[:organisation]).to eq(procedure.organisation) }
|
it { expect(subject[:organisation]).to eq(procedure.organisation) }
|
||||||
it { expect(subject[:direction]).to eq(procedure.direction) }
|
it { expect(subject[:direction]).to eq(procedure.direction) }
|
||||||
it { expect(subject[:archived_at]).to eq(procedure.archived_at) }
|
it { expect(subject[:archived_at]).to eq(procedure.closed_at) }
|
||||||
it { expect(subject[:total_dossier]).to eq(procedure.total_dossier) }
|
it { expect(subject[:total_dossier]).to eq(procedure.total_dossier) }
|
||||||
it { is_expected.to have_key(:types_de_champ) }
|
it { is_expected.to have_key(:types_de_champ) }
|
||||||
it { expect(subject[:types_de_champ]).to be_an(Array) }
|
it { expect(subject[:types_de_champ]).to be_an(Array) }
|
||||||
|
|
|
@ -30,9 +30,9 @@ describe API::V2::GraphqlController do
|
||||||
title
|
title
|
||||||
description
|
description
|
||||||
state
|
state
|
||||||
createdAt
|
dateCreation
|
||||||
updatedAt
|
dateDerniereModification
|
||||||
archivedAt
|
dateFermeture
|
||||||
groupeInstructeurs {
|
groupeInstructeurs {
|
||||||
label
|
label
|
||||||
instructeurs {
|
instructeurs {
|
||||||
|
@ -80,9 +80,9 @@ describe API::V2::GraphqlController do
|
||||||
title: procedure.libelle,
|
title: procedure.libelle,
|
||||||
description: procedure.description,
|
description: procedure.description,
|
||||||
state: 'brouillon',
|
state: 'brouillon',
|
||||||
archivedAt: nil,
|
dateFermeture: nil,
|
||||||
createdAt: procedure.created_at.iso8601,
|
dateCreation: procedure.created_at.iso8601,
|
||||||
updatedAt: procedure.updated_at.iso8601,
|
dateDerniereModification: procedure.updated_at.iso8601,
|
||||||
groupeInstructeurs: [
|
groupeInstructeurs: [
|
||||||
{
|
{
|
||||||
instructeurs: [{ email: instructeur.email }],
|
instructeurs: [{ email: instructeur.email }],
|
||||||
|
@ -139,7 +139,7 @@ describe API::V2::GraphqlController do
|
||||||
id
|
id
|
||||||
number
|
number
|
||||||
state
|
state
|
||||||
updatedAt
|
dateDerniereModification
|
||||||
datePassageEnConstruction
|
datePassageEnConstruction
|
||||||
datePassageEnInstruction
|
datePassageEnInstruction
|
||||||
dateTraitement
|
dateTraitement
|
||||||
|
@ -159,9 +159,13 @@ describe API::V2::GraphqlController do
|
||||||
attachmentUrl
|
attachmentUrl
|
||||||
}
|
}
|
||||||
avis {
|
avis {
|
||||||
|
expert {
|
||||||
email
|
email
|
||||||
|
}
|
||||||
question
|
question
|
||||||
answer
|
reponse
|
||||||
|
dateQuestion
|
||||||
|
dateReponse
|
||||||
attachmentUrl
|
attachmentUrl
|
||||||
}
|
}
|
||||||
champs {
|
champs {
|
||||||
|
@ -179,7 +183,7 @@ describe API::V2::GraphqlController do
|
||||||
id: dossier.to_typed_id,
|
id: dossier.to_typed_id,
|
||||||
number: dossier.id,
|
number: dossier.id,
|
||||||
state: 'en_construction',
|
state: 'en_construction',
|
||||||
updatedAt: dossier.updated_at.iso8601,
|
dateDerniereModification: dossier.updated_at.iso8601,
|
||||||
datePassageEnConstruction: dossier.en_construction_at.iso8601,
|
datePassageEnConstruction: dossier.en_construction_at.iso8601,
|
||||||
datePassageEnInstruction: nil,
|
datePassageEnInstruction: nil,
|
||||||
dateTraitement: nil,
|
dateTraitement: nil,
|
||||||
|
|
|
@ -99,7 +99,7 @@ describe Instructeurs::ProceduresController, type: :controller do
|
||||||
|
|
||||||
context "with procedures assigned" do
|
context "with procedures assigned" do
|
||||||
let(:procedure1) { create(:procedure, :published) }
|
let(:procedure1) { create(:procedure, :published) }
|
||||||
let(:procedure2) { create(:procedure, :archived) }
|
let(:procedure2) { create(:procedure, :closed) }
|
||||||
let(:procedure3) { create(:procedure) }
|
let(:procedure3) { create(:procedure) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
|
|
|
@ -117,6 +117,12 @@ describe NewAdministrateur::GroupeInstructeursController, type: :controller do
|
||||||
it { expect(flash.alert).to be_present }
|
it { expect(flash.alert).to be_present }
|
||||||
it { expect(response).to redirect_to(procedure_groupe_instructeur_path(procedure, procedure.defaut_groupe_instructeur)) }
|
it { expect(response).to redirect_to(procedure_groupe_instructeur_path(procedure, procedure.defaut_groupe_instructeur)) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'of an empty string' do
|
||||||
|
let(:new_instructeur_emails) { '' }
|
||||||
|
|
||||||
|
it { expect(response).to redirect_to(procedure_groupe_instructeur_path(procedure, procedure.defaut_groupe_instructeur)) }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#remove_instructeur' do
|
describe '#remove_instructeur' do
|
||||||
|
|
|
@ -423,8 +423,8 @@ describe Users::DossiersController, type: :controller do
|
||||||
expect(dossier.reload.state).to eq(Dossier.states.fetch(:en_construction))
|
expect(dossier.reload.state).to eq(Dossier.states.fetch(:en_construction))
|
||||||
end
|
end
|
||||||
|
|
||||||
context "on an archived procedure" do
|
context "on an closed procedure" do
|
||||||
before { dossier.procedure.archive }
|
before { dossier.procedure.close! }
|
||||||
|
|
||||||
it "it does not change state" do
|
it "it does not change state" do
|
||||||
subject
|
subject
|
||||||
|
@ -873,8 +873,8 @@ describe Users::DossiersController, type: :controller do
|
||||||
it { is_expected.to redirect_to identite_dossier_path(id: Dossier.last) }
|
it { is_expected.to redirect_to identite_dossier_path(id: Dossier.last) }
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when procedure is archived' do
|
context 'when procedure is closed' do
|
||||||
let(:procedure) { create(:procedure, :archived) }
|
let(:procedure) { create(:procedure, :closed) }
|
||||||
|
|
||||||
it { is_expected.to redirect_to dossiers_path }
|
it { is_expected.to redirect_to dossiers_path }
|
||||||
end
|
end
|
||||||
|
|
|
@ -160,21 +160,11 @@ FactoryBot.define do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
trait :archived do
|
trait :closed do
|
||||||
after(:build) do |procedure, _evaluator|
|
after(:build) do |procedure, _evaluator|
|
||||||
procedure.path = generate(:published_path)
|
procedure.path = generate(:published_path)
|
||||||
procedure.publish!
|
procedure.publish!
|
||||||
procedure.archive!
|
procedure.close!
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
trait :archived_automatically do
|
|
||||||
# For now the behavior is the same than :archived
|
|
||||||
# (it may be different in the future though)
|
|
||||||
after(:build) do |procedure, _evaluator|
|
|
||||||
procedure.path = generate(:published_path)
|
|
||||||
procedure.publish!
|
|
||||||
procedure.archive!
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -25,10 +25,10 @@ feature "procedure filters" do
|
||||||
|
|
||||||
scenario "should list all dossiers" do
|
scenario "should list all dossiers" do
|
||||||
within ".dossiers-table" do
|
within ".dossiers-table" do
|
||||||
expect(page).to have_link(new_unfollow_dossier.id)
|
expect(page).to have_link(new_unfollow_dossier.id.to_s)
|
||||||
expect(page).to have_link(new_unfollow_dossier.user.email)
|
expect(page).to have_link(new_unfollow_dossier.user.email)
|
||||||
|
|
||||||
expect(page).to have_link(new_unfollow_dossier_2.id)
|
expect(page).to have_link(new_unfollow_dossier_2.id.to_s)
|
||||||
expect(page).to have_link(new_unfollow_dossier_2.user.email)
|
expect(page).to have_link(new_unfollow_dossier_2.user.email)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -61,20 +61,20 @@ feature "procedure filters" do
|
||||||
expect(page).to have_content("#{type_de_champ.libelle} : #{champ.value}")
|
expect(page).to have_content("#{type_de_champ.libelle} : #{champ.value}")
|
||||||
|
|
||||||
within ".dossiers-table" do
|
within ".dossiers-table" do
|
||||||
expect(page).to have_link(new_unfollow_dossier.id, exact: true)
|
expect(page).to have_link(new_unfollow_dossier.id.to_s, exact: true)
|
||||||
expect(page).to have_link(new_unfollow_dossier.user.email)
|
expect(page).to have_link(new_unfollow_dossier.user.email)
|
||||||
|
|
||||||
expect(page).not_to have_link(new_unfollow_dossier_2.id, exact: true)
|
expect(page).not_to have_link(new_unfollow_dossier_2.id.to_s, exact: true)
|
||||||
expect(page).not_to have_link(new_unfollow_dossier_2.user.email)
|
expect(page).not_to have_link(new_unfollow_dossier_2.user.email)
|
||||||
end
|
end
|
||||||
|
|
||||||
remove_filter(champ.value)
|
remove_filter(champ.value)
|
||||||
|
|
||||||
within ".dossiers-table" do
|
within ".dossiers-table" do
|
||||||
expect(page).to have_link(new_unfollow_dossier.id)
|
expect(page).to have_link(new_unfollow_dossier.id.to_s)
|
||||||
expect(page).to have_link(new_unfollow_dossier.user.email)
|
expect(page).to have_link(new_unfollow_dossier.user.email)
|
||||||
|
|
||||||
expect(page).to have_link(new_unfollow_dossier_2.id)
|
expect(page).to have_link(new_unfollow_dossier_2.id.to_s)
|
||||||
expect(page).to have_link(new_unfollow_dossier_2.user.email)
|
expect(page).to have_link(new_unfollow_dossier_2.user.email)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -86,30 +86,30 @@ feature "procedure filters" do
|
||||||
expect(page).to have_content("#{type_de_champ.libelle} : #{champ.value}")
|
expect(page).to have_content("#{type_de_champ.libelle} : #{champ.value}")
|
||||||
|
|
||||||
within ".dossiers-table" do
|
within ".dossiers-table" do
|
||||||
expect(page).to have_link(new_unfollow_dossier.id, exact: true)
|
expect(page).to have_link(new_unfollow_dossier.id.to_s, exact: true)
|
||||||
expect(page).to have_link(new_unfollow_dossier.user.email)
|
expect(page).to have_link(new_unfollow_dossier.user.email)
|
||||||
|
|
||||||
expect(page).to have_link(new_unfollow_dossier_2.id, exact: true)
|
expect(page).to have_link(new_unfollow_dossier_2.id.to_s, exact: true)
|
||||||
expect(page).to have_link(new_unfollow_dossier_2.user.email)
|
expect(page).to have_link(new_unfollow_dossier_2.user.email)
|
||||||
end
|
end
|
||||||
|
|
||||||
remove_filter(champ.value)
|
remove_filter(champ.value)
|
||||||
|
|
||||||
within ".dossiers-table" do
|
within ".dossiers-table" do
|
||||||
expect(page).not_to have_link(new_unfollow_dossier.id, exact: true)
|
expect(page).not_to have_link(new_unfollow_dossier.id.to_s, exact: true)
|
||||||
expect(page).not_to have_link(new_unfollow_dossier.user.email)
|
expect(page).not_to have_link(new_unfollow_dossier.user.email)
|
||||||
|
|
||||||
expect(page).to have_link(new_unfollow_dossier_2.id, exact: true)
|
expect(page).to have_link(new_unfollow_dossier_2.id.to_s, exact: true)
|
||||||
expect(page).to have_link(new_unfollow_dossier_2.user.email)
|
expect(page).to have_link(new_unfollow_dossier_2.user.email)
|
||||||
end
|
end
|
||||||
|
|
||||||
remove_filter(champ_2.value)
|
remove_filter(champ_2.value)
|
||||||
|
|
||||||
within ".dossiers-table" do
|
within ".dossiers-table" do
|
||||||
expect(page).to have_link(new_unfollow_dossier.id, exact: true)
|
expect(page).to have_link(new_unfollow_dossier.id.to_s, exact: true)
|
||||||
expect(page).to have_link(new_unfollow_dossier.user.email)
|
expect(page).to have_link(new_unfollow_dossier.user.email)
|
||||||
|
|
||||||
expect(page).to have_link(new_unfollow_dossier_2.id, exact: true)
|
expect(page).to have_link(new_unfollow_dossier_2.id.to_s, exact: true)
|
||||||
expect(page).to have_link(new_unfollow_dossier_2.user.email)
|
expect(page).to have_link(new_unfollow_dossier_2.user.email)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -104,13 +104,13 @@ feature 'Invitations' do
|
||||||
|
|
||||||
def navigate_to_brouillon(dossier)
|
def navigate_to_brouillon(dossier)
|
||||||
expect(page).to have_current_path(dossiers_path)
|
expect(page).to have_current_path(dossiers_path)
|
||||||
click_on(dossier.id)
|
click_on(dossier.id.to_s)
|
||||||
expect(page).to have_current_path(brouillon_dossier_path(dossier))
|
expect(page).to have_current_path(brouillon_dossier_path(dossier))
|
||||||
end
|
end
|
||||||
|
|
||||||
def navigate_to_dossier(dossier)
|
def navigate_to_dossier(dossier)
|
||||||
expect(page).to have_current_path(dossiers_path)
|
expect(page).to have_current_path(dossiers_path)
|
||||||
click_on(dossier.id)
|
click_on(dossier.id.to_s)
|
||||||
expect(page).to have_current_path(dossier_path(dossier))
|
expect(page).to have_current_path(dossier_path(dossier))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -49,8 +49,8 @@ RSpec.describe DossierHelper, type: :helper do
|
||||||
context "when dossier state is brouillon" do
|
context "when dossier state is brouillon" do
|
||||||
it { is_expected.to be false }
|
it { is_expected.to be false }
|
||||||
|
|
||||||
context "when dossier state is brouillon and procedure is archivee" do
|
context "when dossier state is brouillon and procedure is close" do
|
||||||
before { dossier.procedure.archive }
|
before { dossier.procedure.close }
|
||||||
|
|
||||||
it { is_expected.to be true }
|
it { is_expected.to be true }
|
||||||
end
|
end
|
||||||
|
@ -59,8 +59,8 @@ RSpec.describe DossierHelper, type: :helper do
|
||||||
shared_examples_for "returns false" do
|
shared_examples_for "returns false" do
|
||||||
it { is_expected.to be false }
|
it { is_expected.to be false }
|
||||||
|
|
||||||
context "and procedure is archivee" do
|
context "and procedure is close" do
|
||||||
before { dossier.procedure.archive }
|
before { dossier.procedure.close }
|
||||||
|
|
||||||
it { is_expected.to be false }
|
it { is_expected.to be false }
|
||||||
end
|
end
|
||||||
|
|
|
@ -14,7 +14,7 @@ RSpec.describe AutoArchiveProcedureJob, type: :job do
|
||||||
procedure.reload
|
procedure.reload
|
||||||
end
|
end
|
||||||
|
|
||||||
it { expect(procedure.archivee?).to eq false }
|
it { expect(procedure.close?).to eq false }
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when procedures have auto_archive_on set on yesterday or today" do
|
context "when procedures have auto_archive_on set on yesterday or today" do
|
||||||
|
@ -53,8 +53,8 @@ RSpec.describe AutoArchiveProcedureJob, type: :job do
|
||||||
}
|
}
|
||||||
|
|
||||||
it {
|
it {
|
||||||
expect(procedure_hier.archivee?).to eq true
|
expect(procedure_hier.close?).to eq true
|
||||||
expect(procedure_aujourdhui.archivee?).to eq true
|
expect(procedure_aujourdhui.close?).to eq true
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -63,6 +63,6 @@ RSpec.describe AutoArchiveProcedureJob, type: :job do
|
||||||
subject
|
subject
|
||||||
end
|
end
|
||||||
|
|
||||||
it { expect(procedure_demain.archivee?).to eq false }
|
it { expect(procedure_demain.close?).to eq false }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -40,8 +40,8 @@ RSpec.describe FindDubiousProceduresJob, type: :job do
|
||||||
it { expect(AdministrationMailer).to have_received(:dubious_procedures).with([]) }
|
it { expect(AdministrationMailer).to have_received(:dubious_procedures).with([]) }
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'and a archived procedure' do
|
context 'and a closed procedure' do
|
||||||
let(:procedure) { create(:procedure, :archived) }
|
let(:procedure) { create(:procedure, :closed) }
|
||||||
|
|
||||||
it { expect(AdministrationMailer).to have_received(:dubious_procedures).with([]) }
|
it { expect(AdministrationMailer).to have_received(:dubious_procedures).with([]) }
|
||||||
end
|
end
|
||||||
|
|
|
@ -702,8 +702,8 @@ describe Dossier do
|
||||||
let(:state) { Dossier.states.fetch(:brouillon) }
|
let(:state) { Dossier.states.fetch(:brouillon) }
|
||||||
it { is_expected.to be true }
|
it { is_expected.to be true }
|
||||||
|
|
||||||
context "procedure is archived" do
|
context "procedure is closed" do
|
||||||
before { procedure.archive }
|
before { procedure.close! }
|
||||||
it { is_expected.to be false }
|
it { is_expected.to be false }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -356,17 +356,17 @@ describe Procedure do
|
||||||
let(:procedure) { create(:procedure) }
|
let(:procedure) { create(:procedure) }
|
||||||
subject { Procedure.active(procedure.id) }
|
subject { Procedure.active(procedure.id) }
|
||||||
|
|
||||||
context 'when procedure is in draft status and not archived' do
|
context 'when procedure is in draft status and not closed' do
|
||||||
it { expect { subject }.to raise_error(ActiveRecord::RecordNotFound) }
|
it { expect { subject }.to raise_error(ActiveRecord::RecordNotFound) }
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when procedure is published and not archived' do
|
context 'when procedure is published and not closed' do
|
||||||
let(:procedure) { create(:procedure, :published) }
|
let(:procedure) { create(:procedure, :published) }
|
||||||
it { is_expected.to be_truthy }
|
it { is_expected.to be_truthy }
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when procedure is published and archived' do
|
context 'when procedure is published and closed' do
|
||||||
let(:procedure) { create(:procedure, :archived) }
|
let(:procedure) { create(:procedure, :closed) }
|
||||||
it { expect { subject }.to raise_error(ActiveRecord::RecordNotFound) }
|
it { expect { subject }.to raise_error(ActiveRecord::RecordNotFound) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -509,12 +509,11 @@ describe Procedure do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'procedure status is reset' do
|
describe 'procedure status is reset' do
|
||||||
let(:procedure) { create(:procedure, :archived, received_mail: received_mail, service: service) }
|
let(:procedure) { create(:procedure, :closed, received_mail: received_mail, service: service) }
|
||||||
|
|
||||||
it 'Not published nor archived' do
|
it 'Not published nor closed' do
|
||||||
expect(subject.archived_at).to be_nil
|
expect(subject.closed_at).to be_nil
|
||||||
expect(subject.published_at).to be_nil
|
expect(subject.published_at).to be_nil
|
||||||
expect(subject.test_started_at).to be_nil
|
|
||||||
expect(subject.aasm_state).to eq "brouillon"
|
expect(subject.aasm_state).to eq "brouillon"
|
||||||
expect(subject.path).not_to be_nil
|
expect(subject.path).not_to be_nil
|
||||||
end
|
end
|
||||||
|
@ -556,7 +555,7 @@ describe Procedure do
|
||||||
end
|
end
|
||||||
after { Timecop.return }
|
after { Timecop.return }
|
||||||
|
|
||||||
it { expect(procedure.archived_at).to eq(nil) }
|
it { expect(procedure.closed_at).to eq(nil) }
|
||||||
it { expect(procedure.published_at).to eq(now) }
|
it { expect(procedure.published_at).to eq(now) }
|
||||||
it { expect(Procedure.find_by(path: "example-path")).to eq(procedure) }
|
it { expect(Procedure.find_by(path: "example-path")).to eq(procedure) }
|
||||||
it { expect(Procedure.find_by(path: "example-path").administrateurs).to eq(procedure.administrateurs) }
|
it { expect(Procedure.find_by(path: "example-path").administrateurs).to eq(procedure.administrateurs) }
|
||||||
|
@ -565,41 +564,41 @@ describe Procedure do
|
||||||
describe "#brouillon?" do
|
describe "#brouillon?" do
|
||||||
let(:procedure_brouillon) { Procedure.new() }
|
let(:procedure_brouillon) { Procedure.new() }
|
||||||
let(:procedure_publiee) { Procedure.new(aasm_state: :publiee, published_at: Time.zone.now) }
|
let(:procedure_publiee) { Procedure.new(aasm_state: :publiee, published_at: Time.zone.now) }
|
||||||
let(:procedure_archivee) { Procedure.new(aasm_state: :archivee, published_at: Time.zone.now, archived_at: Time.zone.now) }
|
let(:procedure_close) { Procedure.new(aasm_state: :close, published_at: Time.zone.now, closed_at: Time.zone.now) }
|
||||||
|
|
||||||
it { expect(procedure_brouillon.brouillon?).to be_truthy }
|
it { expect(procedure_brouillon.brouillon?).to be_truthy }
|
||||||
it { expect(procedure_publiee.brouillon?).to be_falsey }
|
it { expect(procedure_publiee.brouillon?).to be_falsey }
|
||||||
it { expect(procedure_archivee.brouillon?).to be_falsey }
|
it { expect(procedure_close.brouillon?).to be_falsey }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#publiee?" do
|
describe "#publiee?" do
|
||||||
let(:procedure_brouillon) { Procedure.new() }
|
let(:procedure_brouillon) { Procedure.new() }
|
||||||
let(:procedure_publiee) { Procedure.new(aasm_state: :publiee, published_at: Time.zone.now) }
|
let(:procedure_publiee) { Procedure.new(aasm_state: :publiee, published_at: Time.zone.now) }
|
||||||
let(:procedure_archivee) { Procedure.new(aasm_state: :archivee, published_at: Time.zone.now, archived_at: Time.zone.now) }
|
let(:procedure_close) { Procedure.new(aasm_state: :close, published_at: Time.zone.now, closed_at: Time.zone.now) }
|
||||||
|
|
||||||
it { expect(procedure_brouillon.publiee?).to be_falsey }
|
it { expect(procedure_brouillon.publiee?).to be_falsey }
|
||||||
it { expect(procedure_publiee.publiee?).to be_truthy }
|
it { expect(procedure_publiee.publiee?).to be_truthy }
|
||||||
it { expect(procedure_archivee.publiee?).to be_falsey }
|
it { expect(procedure_close.publiee?).to be_falsey }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#archivee?" do
|
describe "#close?" do
|
||||||
let(:procedure_brouillon) { Procedure.new() }
|
let(:procedure_brouillon) { Procedure.new() }
|
||||||
let(:procedure_publiee) { Procedure.new(aasm_state: :publiee, published_at: Time.zone.now) }
|
let(:procedure_publiee) { Procedure.new(aasm_state: :publiee, published_at: Time.zone.now) }
|
||||||
let(:procedure_archivee) { Procedure.new(aasm_state: :archivee, published_at: Time.zone.now, archived_at: Time.zone.now) }
|
let(:procedure_close) { Procedure.new(aasm_state: :close, published_at: Time.zone.now, closed_at: Time.zone.now) }
|
||||||
|
|
||||||
it { expect(procedure_brouillon.archivee?).to be_falsey }
|
it { expect(procedure_brouillon.close?).to be_falsey }
|
||||||
it { expect(procedure_publiee.archivee?).to be_falsey }
|
it { expect(procedure_publiee.close?).to be_falsey }
|
||||||
it { expect(procedure_archivee.archivee?).to be_truthy }
|
it { expect(procedure_close.close?).to be_truthy }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#publiee_ou_archivee?" do
|
describe "#publiee_ou_close?" do
|
||||||
let(:procedure_brouillon) { Procedure.new() }
|
let(:procedure_brouillon) { Procedure.new() }
|
||||||
let(:procedure_publiee) { Procedure.new(aasm_state: :publiee, published_at: Time.zone.now) }
|
let(:procedure_publiee) { Procedure.new(aasm_state: :publiee, published_at: Time.zone.now) }
|
||||||
let(:procedure_archivee) { Procedure.new(aasm_state: :archivee, published_at: Time.zone.now, archived_at: Time.zone.now) }
|
let(:procedure_close) { Procedure.new(aasm_state: :close, published_at: Time.zone.now, closed_at: Time.zone.now) }
|
||||||
|
|
||||||
it { expect(procedure_brouillon.publiee_ou_archivee?).to be_falsey }
|
it { expect(procedure_brouillon.publiee_ou_close?).to be_falsey }
|
||||||
it { expect(procedure_publiee.publiee_ou_archivee?).to be_truthy }
|
it { expect(procedure_publiee.publiee_ou_close?).to be_truthy }
|
||||||
it { expect(procedure_archivee.publiee_ou_archivee?).to be_truthy }
|
it { expect(procedure_close.publiee_ou_close?).to be_truthy }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'archive' do
|
describe 'archive' do
|
||||||
|
@ -607,13 +606,13 @@ describe Procedure do
|
||||||
let(:now) { Time.zone.now.beginning_of_minute }
|
let(:now) { Time.zone.now.beginning_of_minute }
|
||||||
before do
|
before do
|
||||||
Timecop.freeze(now)
|
Timecop.freeze(now)
|
||||||
procedure.archive!
|
procedure.close!
|
||||||
procedure.reload
|
procedure.reload
|
||||||
end
|
end
|
||||||
after { Timecop.return }
|
after { Timecop.return }
|
||||||
|
|
||||||
it { expect(procedure.archivee?).to be_truthy }
|
it { expect(procedure.close?).to be_truthy }
|
||||||
it { expect(procedure.archived_at).to eq(now) }
|
it { expect(procedure.closed_at).to eq(now) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'path_customized?' do
|
describe 'path_customized?' do
|
||||||
|
|
|
@ -83,8 +83,8 @@ describe AdministrateurUsageStatisticsService do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with a procedure archivee' do
|
context 'with a procedure close' do
|
||||||
let(:procedure) { create(:procedure, aasm_state: 'archivee') }
|
let(:procedure) { create(:procedure, aasm_state: 'close') }
|
||||||
let!(:dossiers) do
|
let!(:dossiers) do
|
||||||
(1..7).flat_map do
|
(1..7).flat_map do
|
||||||
[
|
[
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
describe 'admin/procedures/show.html.haml', type: :view do
|
describe 'admin/procedures/show.html.haml', type: :view do
|
||||||
let(:archived_at) { nil }
|
let(:closed_at) { nil }
|
||||||
let(:procedure) { create(:procedure, :with_service, archived_at: archived_at) }
|
let(:procedure) { create(:procedure, :with_service, closed_at: closed_at) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
assign(:procedure, procedure)
|
assign(:procedure, procedure)
|
||||||
|
@ -58,10 +58,10 @@ describe 'admin/procedures/show.html.haml', type: :view do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'procedure is archived' do
|
describe 'procedure is closed' do
|
||||||
before do
|
before do
|
||||||
procedure.publish!
|
procedure.publish!
|
||||||
procedure.archive!
|
procedure.close!
|
||||||
procedure.reload
|
procedure.reload
|
||||||
render
|
render
|
||||||
end
|
end
|
||||||
|
@ -73,7 +73,7 @@ describe 'admin/procedures/show.html.haml', type: :view do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'procedure link is present' do
|
describe 'procedure link is present' do
|
||||||
it { expect(rendered).to have_content('Cette démarche est archivée et n’est donc plus accessible par le public.') }
|
it { expect(rendered).to have_content('Cette démarche est close et n’est donc plus accessible par le public.') }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -13,12 +13,12 @@ describe 'users/dossiers/dossier_actions.html.haml', type: :view do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when the procedure is closed' do
|
context 'when the procedure is closed' do
|
||||||
let(:procedure) { create(:procedure, :archived) }
|
let(:procedure) { create(:procedure, :closed) }
|
||||||
it { is_expected.not_to have_link('Commencer un autre dossier') }
|
it { is_expected.not_to have_link('Commencer un autre dossier') }
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when there are no actions to display' do
|
context 'when there are no actions to display' do
|
||||||
let(:procedure) { create(:procedure, :archived) }
|
let(:procedure) { create(:procedure, :closed) }
|
||||||
let(:dossier) { create(:dossier, :accepte, procedure: procedure) }
|
let(:dossier) { create(:dossier, :accepte, procedure: procedure) }
|
||||||
|
|
||||||
it 'doesn’t render the menu at all' do
|
it 'doesn’t render the menu at all' do
|
||||||
|
|
|
@ -24,13 +24,13 @@ describe 'users/dossiers/index.html.haml', type: :view do
|
||||||
|
|
||||||
it 'affiche les informations des dossiers' do
|
it 'affiche les informations des dossiers' do
|
||||||
dossier = user_dossiers.first
|
dossier = user_dossiers.first
|
||||||
expect(rendered).to have_text(dossier_brouillon.id)
|
expect(rendered).to have_text(dossier_brouillon.id.to_s)
|
||||||
expect(rendered).to have_text(dossier_brouillon.procedure.libelle)
|
expect(rendered).to have_text(dossier_brouillon.procedure.libelle)
|
||||||
expect(rendered).to have_link(dossier_brouillon.id, href: brouillon_dossier_path(dossier_brouillon))
|
expect(rendered).to have_link(dossier_brouillon.id.to_s, href: brouillon_dossier_path(dossier_brouillon))
|
||||||
|
|
||||||
expect(rendered).to have_text(dossier_en_construction.id)
|
expect(rendered).to have_text(dossier_en_construction.id.to_s)
|
||||||
expect(rendered).to have_text(dossier_en_construction.procedure.libelle)
|
expect(rendered).to have_text(dossier_en_construction.procedure.libelle)
|
||||||
expect(rendered).to have_link(dossier_en_construction.id, href: dossier_path(dossier_en_construction))
|
expect(rendered).to have_link(dossier_en_construction.id.to_s, href: dossier_path(dossier_en_construction))
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'quand il n’y a aucun dossier' do
|
context 'quand il n’y a aucun dossier' do
|
||||||
|
|
|
@ -6953,7 +6953,7 @@ promise-inflight@^1.0.1:
|
||||||
resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3"
|
resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3"
|
||||||
integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM=
|
integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM=
|
||||||
|
|
||||||
prop-types@^15.5.10, prop-types@^15.5.7, prop-types@^15.6.2, prop-types@^15.7.2:
|
prop-types@^15.5.0, prop-types@^15.5.10, prop-types@^15.5.7, prop-types@^15.6.2, prop-types@^15.7.2:
|
||||||
version "15.7.2"
|
version "15.7.2"
|
||||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
|
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
|
||||||
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
|
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
|
||||||
|
@ -7142,6 +7142,13 @@ react-is@^16.8.1:
|
||||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.6.tgz#5bbc1e2d29141c9fbdfed456343fe2bc430a6a16"
|
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.6.tgz#5bbc1e2d29141c9fbdfed456343fe2bc430a6a16"
|
||||||
integrity sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==
|
integrity sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==
|
||||||
|
|
||||||
|
react-loadable@^5.5.0:
|
||||||
|
version "5.5.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-loadable/-/react-loadable-5.5.0.tgz#582251679d3da86c32aae2c8e689c59f1196d8c4"
|
||||||
|
integrity sha512-C8Aui0ZpMd4KokxRdVAm2bQtI03k2RMRNzOB+IipV3yxFTSVICv7WoUr5L9ALB5BmKO1iHgZtWM8EvYG83otdg==
|
||||||
|
dependencies:
|
||||||
|
prop-types "^15.5.0"
|
||||||
|
|
||||||
react-scroll-to-component@^1.0.2:
|
react-scroll-to-component@^1.0.2:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/react-scroll-to-component/-/react-scroll-to-component-1.0.2.tgz#f260dc936c62a53e772786d7832fe0884e195354"
|
resolved "https://registry.yarnpkg.com/react-scroll-to-component/-/react-scroll-to-component-1.0.2.tgz#f260dc936c62a53e772786d7832fe0884e195354"
|
||||||
|
|
Loading…
Reference in a new issue