Merge pull request #8117 from tchak/graphql-complete-demarche
feat(graphql): expose more information on demarche descriptor
This commit is contained in:
commit
357290acf7
48 changed files with 1759 additions and 92 deletions
|
@ -22,11 +22,15 @@ class API::V2::Context < GraphQL::Query::Context
|
|||
Administrateur.find(self[:administrateur_id])
|
||||
end
|
||||
|
||||
def authorized_demarche?(demarche)
|
||||
def authorized_demarche?(demarche, opendata: false)
|
||||
if internal_use?
|
||||
return true
|
||||
end
|
||||
|
||||
if opendata && demarche.opendata?
|
||||
return true
|
||||
end
|
||||
|
||||
# We are caching authorization logic because it is called for each node
|
||||
# of the requested graph and can be expensive. Context is reset per request so it is safe.
|
||||
self[:authorized] ||= Hash.new do |hash, demarche_id|
|
||||
|
|
|
@ -75,7 +75,42 @@ class API::V2::Schema < GraphQL::Schema
|
|||
Types::GeoAreas::ParcelleCadastraleType,
|
||||
Types::GeoAreas::SelectionUtilisateurType,
|
||||
Types::PersonneMoraleType,
|
||||
Types::PersonnePhysiqueType
|
||||
Types::PersonnePhysiqueType,
|
||||
Types::Champs::Descriptor::AddressChampDescriptorType,
|
||||
Types::Champs::Descriptor::AnnuaireEducationChampDescriptorType,
|
||||
Types::Champs::Descriptor::CarteChampDescriptorType,
|
||||
Types::Champs::Descriptor::CheckboxChampDescriptorType,
|
||||
Types::Champs::Descriptor::CiviliteChampDescriptorType,
|
||||
Types::Champs::Descriptor::CnafChampDescriptorType,
|
||||
Types::Champs::Descriptor::CommuneChampDescriptorType,
|
||||
Types::Champs::Descriptor::DateChampDescriptorType,
|
||||
Types::Champs::Descriptor::DatetimeChampDescriptorType,
|
||||
Types::Champs::Descriptor::DecimalNumberChampDescriptorType,
|
||||
Types::Champs::Descriptor::DepartementChampDescriptorType,
|
||||
Types::Champs::Descriptor::DgfipChampDescriptorType,
|
||||
Types::Champs::Descriptor::DossierLinkChampDescriptorType,
|
||||
Types::Champs::Descriptor::DropDownListChampDescriptorType,
|
||||
Types::Champs::Descriptor::EmailChampDescriptorType,
|
||||
Types::Champs::Descriptor::ExplicationChampDescriptorType,
|
||||
Types::Champs::Descriptor::HeaderSectionChampDescriptorType,
|
||||
Types::Champs::Descriptor::IbanChampDescriptorType,
|
||||
Types::Champs::Descriptor::IntegerNumberChampDescriptorType,
|
||||
Types::Champs::Descriptor::LinkedDropDownListChampDescriptorType,
|
||||
Types::Champs::Descriptor::MesriChampDescriptorType,
|
||||
Types::Champs::Descriptor::MultipleDropDownListChampDescriptorType,
|
||||
Types::Champs::Descriptor::NumberChampDescriptorType,
|
||||
Types::Champs::Descriptor::PaysChampDescriptorType,
|
||||
Types::Champs::Descriptor::PhoneChampDescriptorType,
|
||||
Types::Champs::Descriptor::PieceJustificativeChampDescriptorType,
|
||||
Types::Champs::Descriptor::PoleEmploiChampDescriptorType,
|
||||
Types::Champs::Descriptor::RegionChampDescriptorType,
|
||||
Types::Champs::Descriptor::RepetitionChampDescriptorType,
|
||||
Types::Champs::Descriptor::RNAChampDescriptorType,
|
||||
Types::Champs::Descriptor::SiretChampDescriptorType,
|
||||
Types::Champs::Descriptor::TextChampDescriptorType,
|
||||
Types::Champs::Descriptor::TextareaChampDescriptorType,
|
||||
Types::Champs::Descriptor::TitreIdentiteChampDescriptorType,
|
||||
Types::Champs::Descriptor::YesNoChampDescriptorType
|
||||
|
||||
def self.unauthorized_object(error)
|
||||
# Add a top-level error to the response instead of returning nil:
|
||||
|
|
|
@ -50,7 +50,7 @@ class API::V2::StoredQuery
|
|||
declarative
|
||||
dateCreation
|
||||
dateFermeture
|
||||
publishedRevision @include(if: $includeRevision) {
|
||||
activeRevision @include(if: $includeRevision) {
|
||||
...RevisionFragment
|
||||
}
|
||||
groupeInstructeurs @include(if: $includeGroupeInstructeurs) {
|
||||
|
@ -305,25 +305,65 @@ class API::V2::StoredQuery
|
|||
datePublication
|
||||
champDescriptors {
|
||||
...ChampDescriptorFragment
|
||||
champDescriptors {
|
||||
...ChampDescriptorFragment
|
||||
... on RepetitionChampDescriptor {
|
||||
champDescriptors {
|
||||
...ChampDescriptorFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
annotationDescriptors {
|
||||
...ChampDescriptorFragment
|
||||
champDescriptors {
|
||||
...ChampDescriptorFragment
|
||||
... on RepetitionChampDescriptor {
|
||||
champDescriptors {
|
||||
...ChampDescriptorFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fragment ChampDescriptorFragment on ChampDescriptor {
|
||||
__typename
|
||||
id
|
||||
type
|
||||
label
|
||||
description
|
||||
required
|
||||
options
|
||||
... on DropDownListChampDescriptor {
|
||||
options
|
||||
otherOption
|
||||
}
|
||||
... on MultipleDropDownListChampDescriptor {
|
||||
options
|
||||
}
|
||||
... on LinkedDropDownListChampDescriptor {
|
||||
options
|
||||
}
|
||||
... on PieceJustificativeChampDescriptor {
|
||||
fileTemplate {
|
||||
...FileFragment
|
||||
}
|
||||
}
|
||||
... on ExplicationChampDescriptor {
|
||||
collapsibleExplanationEnabled
|
||||
collapsibleExplanationText
|
||||
}
|
||||
... on PaysChampDescriptor {
|
||||
options {
|
||||
name
|
||||
code
|
||||
}
|
||||
}
|
||||
... on RegionChampDescriptor {
|
||||
options {
|
||||
name
|
||||
code
|
||||
}
|
||||
}
|
||||
... on DepartementChampDescriptor {
|
||||
options {
|
||||
name
|
||||
code
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fragment AvisFragment on Avis {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
module Extensions
|
||||
class Attachment < GraphQL::Schema::FieldExtension
|
||||
attr_reader :attachment_assoc
|
||||
attr_reader :attachment_assoc, :root
|
||||
|
||||
def apply
|
||||
# Here we try to define the ActiveRecord association name:
|
||||
|
@ -18,13 +18,14 @@ module Extensions
|
|||
attachment = field.original_name.to_s.sub(/_url$/, "")
|
||||
"#{attachment}_attachment"
|
||||
end
|
||||
@root = options&.dig(:root) || :object
|
||||
end
|
||||
|
||||
# This method resolves (as it states) the field itself
|
||||
# (it's the same as defining a method within a type)
|
||||
def resolve(object:, **_rest)
|
||||
Loaders::Association.for(
|
||||
object.object.class,
|
||||
object.public_send(root).class,
|
||||
attachment_assoc => :blob
|
||||
).load(object.object)
|
||||
end
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,7 @@
|
|||
module Types
|
||||
class ChampDescriptorType < Types::BaseObject
|
||||
module ChampDescriptorType
|
||||
include Types::BaseInterface
|
||||
|
||||
class TypeDeChampType < Types::BaseEnum
|
||||
TypeDeChamp.type_champs.each do |symbol_name, string_name|
|
||||
value(string_name,
|
||||
|
@ -9,24 +11,107 @@ module Types
|
|||
end
|
||||
|
||||
global_id_field :id
|
||||
field :type, TypeDeChampType, "Type de la valeur du champ.", null: false, method: :type_champ
|
||||
field :label, String, "Libellé du champ.", null: false, method: :libelle
|
||||
field :description, String, "Description du champ.", null: true
|
||||
field :required, Boolean, "Est-ce que le champ est obligatoire ?", null: false, method: :mandatory?
|
||||
|
||||
field :champ_descriptors, [Types::ChampDescriptorType], "Description des champs d’un bloc répétable.", null: true
|
||||
field :options, [String], "List des options d’un champ avec selection.", null: true
|
||||
field :options, [String], "List des options d’un champ avec selection.", null: true, deprecation_reason: 'Utilisez le champ `DropDownListChampDescriptor.options` à la place.'
|
||||
field :champ_descriptors, [Types::ChampDescriptorType], "Description des champs d’un bloc répétable.", null: true, deprecation_reason: 'Utilisez le champ `RepetitionChampDescriptor.champ_descriptors` à la place.'
|
||||
field :type, TypeDeChampType, "Type de la valeur du champ.", null: false, method: :type_champ, deprecation_reason: 'Utilisez le champ `__typename` à la place.'
|
||||
|
||||
definition_methods do
|
||||
def resolve_type(object, context)
|
||||
case object.type_champ
|
||||
when TypeDeChamp.type_champs.fetch(:text)
|
||||
Types::Champs::Descriptor::TextChampDescriptorType
|
||||
when TypeDeChamp.type_champs.fetch(:textarea)
|
||||
Types::Champs::Descriptor::TextareaChampDescriptorType
|
||||
when TypeDeChamp.type_champs.fetch(:date)
|
||||
Types::Champs::Descriptor::DateChampDescriptorType
|
||||
when TypeDeChamp.type_champs.fetch(:datetime)
|
||||
Types::Champs::Descriptor::DatetimeChampDescriptorType
|
||||
when TypeDeChamp.type_champs.fetch(:number)
|
||||
Types::Champs::Descriptor::NumberChampDescriptorType
|
||||
when TypeDeChamp.type_champs.fetch(:decimal_number)
|
||||
Types::Champs::Descriptor::DecimalNumberChampDescriptorType
|
||||
when TypeDeChamp.type_champs.fetch(:integer_number)
|
||||
Types::Champs::Descriptor::IntegerNumberChampDescriptorType
|
||||
when TypeDeChamp.type_champs.fetch(:checkbox)
|
||||
Types::Champs::Descriptor::CheckboxChampDescriptorType
|
||||
when TypeDeChamp.type_champs.fetch(:civilite)
|
||||
Types::Champs::Descriptor::CiviliteChampDescriptorType
|
||||
when TypeDeChamp.type_champs.fetch(:email)
|
||||
Types::Champs::Descriptor::EmailChampDescriptorType
|
||||
when TypeDeChamp.type_champs.fetch(:phone)
|
||||
Types::Champs::Descriptor::PhoneChampDescriptorType
|
||||
when TypeDeChamp.type_champs.fetch(:address)
|
||||
Types::Champs::Descriptor::AddressChampDescriptorType
|
||||
when TypeDeChamp.type_champs.fetch(:yes_no)
|
||||
Types::Champs::Descriptor::YesNoChampDescriptorType
|
||||
when TypeDeChamp.type_champs.fetch(:drop_down_list)
|
||||
Types::Champs::Descriptor::DropDownListChampDescriptorType
|
||||
when TypeDeChamp.type_champs.fetch(:multiple_drop_down_list)
|
||||
Types::Champs::Descriptor::MultipleDropDownListChampDescriptorType
|
||||
when TypeDeChamp.type_champs.fetch(:linked_drop_down_list)
|
||||
Types::Champs::Descriptor::LinkedDropDownListChampDescriptorType
|
||||
when TypeDeChamp.type_champs.fetch(:communes)
|
||||
Types::Champs::Descriptor::CommuneChampDescriptorType
|
||||
when TypeDeChamp.type_champs.fetch(:departements)
|
||||
Types::Champs::Descriptor::DepartementChampDescriptorType
|
||||
when TypeDeChamp.type_champs.fetch(:regions)
|
||||
Types::Champs::Descriptor::RegionChampDescriptorType
|
||||
when TypeDeChamp.type_champs.fetch(:pays)
|
||||
Types::Champs::Descriptor::PaysChampDescriptorType
|
||||
when TypeDeChamp.type_champs.fetch(:header_section)
|
||||
Types::Champs::Descriptor::HeaderSectionChampDescriptorType
|
||||
when TypeDeChamp.type_champs.fetch(:explication)
|
||||
Types::Champs::Descriptor::ExplicationChampDescriptorType
|
||||
when TypeDeChamp.type_champs.fetch(:dossier_link)
|
||||
Types::Champs::Descriptor::DossierLinkChampDescriptorType
|
||||
when TypeDeChamp.type_champs.fetch(:piece_justificative)
|
||||
Types::Champs::Descriptor::PieceJustificativeChampDescriptorType
|
||||
when TypeDeChamp.type_champs.fetch(:rna)
|
||||
Types::Champs::Descriptor::RNAChampDescriptorType
|
||||
when TypeDeChamp.type_champs.fetch(:carte)
|
||||
Types::Champs::Descriptor::CarteChampDescriptorType
|
||||
when TypeDeChamp.type_champs.fetch(:repetition)
|
||||
Types::Champs::Descriptor::RepetitionChampDescriptorType
|
||||
when TypeDeChamp.type_champs.fetch(:titre_identite)
|
||||
Types::Champs::Descriptor::TitreIdentiteChampDescriptorType
|
||||
when TypeDeChamp.type_champs.fetch(:iban)
|
||||
Types::Champs::Descriptor::IbanChampDescriptorType
|
||||
when TypeDeChamp.type_champs.fetch(:siret)
|
||||
Types::Champs::Descriptor::SiretChampDescriptorType
|
||||
when TypeDeChamp.type_champs.fetch(:annuaire_education)
|
||||
Types::Champs::Descriptor::AnnuaireEducationChampDescriptorType
|
||||
when TypeDeChamp.type_champs.fetch(:cnaf)
|
||||
Types::Champs::Descriptor::CnafChampDescriptorType
|
||||
when TypeDeChamp.type_champs.fetch(:dgfip)
|
||||
Types::Champs::Descriptor::DgfipChampDescriptorType
|
||||
when TypeDeChamp.type_champs.fetch(:pole_emploi)
|
||||
Types::Champs::Descriptor::PoleEmploiChampDescriptorType
|
||||
when TypeDeChamp.type_champs.fetch(:mesri)
|
||||
Types::Champs::Descriptor::MesriChampDescriptorType
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def champ_descriptors
|
||||
if object.type_de_champ.block?
|
||||
if type_de_champ.block?
|
||||
Loaders::Association.for(object.class, revision_types_de_champ: :type_de_champ).load(object)
|
||||
end
|
||||
end
|
||||
|
||||
def options
|
||||
if object.type_de_champ.drop_down_list?
|
||||
object.type_de_champ.drop_down_list_options.reject(&:empty?)
|
||||
if type_de_champ.drop_down_list?
|
||||
type_de_champ.drop_down_list_options.reject(&:empty?)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def type_de_champ
|
||||
object.type_de_champ
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
module Types::Champs::Descriptor
|
||||
class AddressChampDescriptorType < Types::BaseObject
|
||||
implements Types::ChampDescriptorType
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
module Types::Champs::Descriptor
|
||||
class AnnuaireEducationChampDescriptorType < Types::BaseObject
|
||||
implements Types::ChampDescriptorType
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
module Types::Champs::Descriptor
|
||||
class CarteChampDescriptorType < Types::BaseObject
|
||||
implements Types::ChampDescriptorType
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
module Types::Champs::Descriptor
|
||||
class CheckboxChampDescriptorType < Types::BaseObject
|
||||
implements Types::ChampDescriptorType
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
module Types::Champs::Descriptor
|
||||
class CiviliteChampDescriptorType < Types::BaseObject
|
||||
implements Types::ChampDescriptorType
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
module Types::Champs::Descriptor
|
||||
class CnafChampDescriptorType < Types::BaseObject
|
||||
implements Types::ChampDescriptorType
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
module Types::Champs::Descriptor
|
||||
class CommuneChampDescriptorType < Types::BaseObject
|
||||
implements Types::ChampDescriptorType
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
module Types::Champs::Descriptor
|
||||
class DateChampDescriptorType < Types::BaseObject
|
||||
implements Types::ChampDescriptorType
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
module Types::Champs::Descriptor
|
||||
class DatetimeChampDescriptorType < Types::BaseObject
|
||||
implements Types::ChampDescriptorType
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
module Types::Champs::Descriptor
|
||||
class DecimalNumberChampDescriptorType < Types::BaseObject
|
||||
implements Types::ChampDescriptorType
|
||||
end
|
||||
end
|
|
@ -0,0 +1,11 @@
|
|||
module Types::Champs::Descriptor
|
||||
class DepartementChampDescriptorType < Types::BaseObject
|
||||
implements Types::ChampDescriptorType
|
||||
|
||||
field :options, [Types::Champs::DepartementChampType::DepartementType], "List des departements.", null: true
|
||||
|
||||
def options
|
||||
APIGeoService.departements
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
module Types::Champs::Descriptor
|
||||
class DgfipChampDescriptorType < Types::BaseObject
|
||||
implements Types::ChampDescriptorType
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
module Types::Champs::Descriptor
|
||||
class DossierLinkChampDescriptorType < Types::BaseObject
|
||||
implements Types::ChampDescriptorType
|
||||
end
|
||||
end
|
|
@ -0,0 +1,16 @@
|
|||
module Types::Champs::Descriptor
|
||||
class DropDownListChampDescriptorType < Types::BaseObject
|
||||
implements Types::ChampDescriptorType
|
||||
|
||||
field :options, [String], "List des options d’un champ avec selection.", null: true
|
||||
field :other_option, Boolean, "La selection contien l’option \"Autre\".", null: true
|
||||
|
||||
def other_option
|
||||
object.type_de_champ.drop_down_other?
|
||||
end
|
||||
|
||||
def options
|
||||
object.type_de_champ.drop_down_list_options.reject(&:empty?)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
module Types::Champs::Descriptor
|
||||
class EmailChampDescriptorType < Types::BaseObject
|
||||
implements Types::ChampDescriptorType
|
||||
end
|
||||
end
|
|
@ -0,0 +1,16 @@
|
|||
module Types::Champs::Descriptor
|
||||
class ExplicationChampDescriptorType < Types::BaseObject
|
||||
implements Types::ChampDescriptorType
|
||||
|
||||
field :collapsible_explanation_enabled, Boolean, null: true
|
||||
field :collapsible_explanation_text, String, null: true
|
||||
|
||||
def collapsible_explanation_enabled
|
||||
object.type_de_champ.collapsible_explanation_enabled?
|
||||
end
|
||||
|
||||
def collapsible_explanation_text
|
||||
object.type_de_champ.collapsible_explanation_text
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
module Types::Champs::Descriptor
|
||||
class HeaderSectionChampDescriptorType < Types::BaseObject
|
||||
implements Types::ChampDescriptorType
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
module Types::Champs::Descriptor
|
||||
class IbanChampDescriptorType < Types::BaseObject
|
||||
implements Types::ChampDescriptorType
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
module Types::Champs::Descriptor
|
||||
class IntegerNumberChampDescriptorType < Types::BaseObject
|
||||
implements Types::ChampDescriptorType
|
||||
end
|
||||
end
|
|
@ -0,0 +1,11 @@
|
|||
module Types::Champs::Descriptor
|
||||
class LinkedDropDownListChampDescriptorType < Types::BaseObject
|
||||
implements Types::ChampDescriptorType
|
||||
|
||||
field :options, [String], "List des options d’un champ avec selection.", null: true
|
||||
|
||||
def options
|
||||
object.type_de_champ.drop_down_list_options.reject(&:empty?)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
module Types::Champs::Descriptor
|
||||
class MesriChampDescriptorType < Types::BaseObject
|
||||
implements Types::ChampDescriptorType
|
||||
end
|
||||
end
|
|
@ -0,0 +1,11 @@
|
|||
module Types::Champs::Descriptor
|
||||
class MultipleDropDownListChampDescriptorType < Types::BaseObject
|
||||
implements Types::ChampDescriptorType
|
||||
|
||||
field :options, [String], "List des options d’un champ avec selection.", null: true
|
||||
|
||||
def options
|
||||
object.type_de_champ.drop_down_list_options.reject(&:empty?)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
module Types::Champs::Descriptor
|
||||
class NumberChampDescriptorType < Types::BaseObject
|
||||
implements Types::ChampDescriptorType
|
||||
end
|
||||
end
|
|
@ -0,0 +1,11 @@
|
|||
module Types::Champs::Descriptor
|
||||
class PaysChampDescriptorType < Types::BaseObject
|
||||
implements Types::ChampDescriptorType
|
||||
|
||||
field :options, [Types::Champs::PaysChampType::PaysType], "List des pays.", null: true
|
||||
|
||||
def options
|
||||
APIGeoService.countries
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
module Types::Champs::Descriptor
|
||||
class PhoneChampDescriptorType < Types::BaseObject
|
||||
implements Types::ChampDescriptorType
|
||||
end
|
||||
end
|
|
@ -0,0 +1,9 @@
|
|||
module Types::Champs::Descriptor
|
||||
class PieceJustificativeChampDescriptorType < Types::BaseObject
|
||||
implements Types::ChampDescriptorType
|
||||
|
||||
field :file_template, Types::File, "Modèle de la pièce justificative.", null: true, extensions: [
|
||||
{ Extensions::Attachment => { attachment: :piece_justificative_template, root: :type_de_champ } }
|
||||
]
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
module Types::Champs::Descriptor
|
||||
class PoleEmploiChampDescriptorType < Types::BaseObject
|
||||
implements Types::ChampDescriptorType
|
||||
end
|
||||
end
|
|
@ -0,0 +1,11 @@
|
|||
module Types::Champs::Descriptor
|
||||
class RegionChampDescriptorType < Types::BaseObject
|
||||
implements Types::ChampDescriptorType
|
||||
|
||||
field :options, [Types::Champs::RegionChampType::RegionType], "List des regions.", null: true
|
||||
|
||||
def options
|
||||
APIGeoService.regions
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,11 @@
|
|||
module Types::Champs::Descriptor
|
||||
class RepetitionChampDescriptorType < Types::BaseObject
|
||||
implements Types::ChampDescriptorType
|
||||
|
||||
field :champ_descriptors, [Types::ChampDescriptorType], "Description des champs d’un bloc répétable.", null: true
|
||||
|
||||
def champ_descriptors
|
||||
Loaders::Association.for(object.class, revision_types_de_champ: :type_de_champ).load(object)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
module Types::Champs::Descriptor
|
||||
class RNAChampDescriptorType < Types::BaseObject
|
||||
implements Types::ChampDescriptorType
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
module Types::Champs::Descriptor
|
||||
class SiretChampDescriptorType < Types::BaseObject
|
||||
implements Types::ChampDescriptorType
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
module Types::Champs::Descriptor
|
||||
class TextChampDescriptorType < Types::BaseObject
|
||||
implements Types::ChampDescriptorType
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
module Types::Champs::Descriptor
|
||||
class TextareaChampDescriptorType < Types::BaseObject
|
||||
implements Types::ChampDescriptorType
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
module Types::Champs::Descriptor
|
||||
class TitreIdentiteChampDescriptorType < Types::BaseObject
|
||||
implements Types::ChampDescriptorType
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
module Types::Champs::Descriptor
|
||||
class YesNoChampDescriptorType < Types::BaseObject
|
||||
implements Types::ChampDescriptorType
|
||||
end
|
||||
end
|
|
@ -25,11 +25,24 @@ Cela évite l’accès récursif aux dossiers."
|
|||
field :date_depublication, GraphQL::Types::ISO8601DateTime, "Date de la dépublication.", null: true
|
||||
field :date_fermeture, GraphQL::Types::ISO8601DateTime, "Date de la fermeture.", null: true
|
||||
|
||||
field :duree_conservation_dossiers, Int, "Durée de conservation des dossiers en mois.", null: false
|
||||
|
||||
field :demarche_url, String, null: true
|
||||
field :site_web_url, String, null: true
|
||||
field :dpo_url, String, null: true
|
||||
field :notice_url, String, null: true
|
||||
field :cadre_juridique_url, String, null: true
|
||||
|
||||
field :opendata, Boolean, null: false
|
||||
field :tags, [String], null: false
|
||||
field :zones, [String], null: false
|
||||
|
||||
field :revision, Types::RevisionType, null: false
|
||||
field :service, Types::ServiceType, null: true
|
||||
|
||||
field :cadre_juridique, String, null: true
|
||||
field :deliberation, String, null: true
|
||||
field :logo, Types::File, null: true, extensions: [{ Extensions::Attachment => { root: :procedure } }]
|
||||
field :notice, Types::File, null: true, extensions: [{ Extensions::Attachment => { root: :procedure } }]
|
||||
field :deliberation, Types::File, null: true, extensions: [{ Extensions::Attachment => { root: :procedure } }]
|
||||
|
||||
field :dossiers_count, Int, null: false, internal: true
|
||||
|
||||
|
@ -38,25 +51,51 @@ Cela évite l’accès récursif aux dossiers."
|
|||
end
|
||||
|
||||
def revision
|
||||
object.is_a?(ProcedureRevision) ? object : object.active_revision
|
||||
if object.is_a?(ProcedureRevision)
|
||||
object
|
||||
else
|
||||
object.active_revision
|
||||
end
|
||||
end
|
||||
|
||||
def procedure
|
||||
if object.is_a?(ProcedureRevision)
|
||||
object.procedure
|
||||
else
|
||||
object
|
||||
end
|
||||
end
|
||||
|
||||
def dossiers_count
|
||||
object.dossiers.count
|
||||
end
|
||||
|
||||
def deliberation
|
||||
Rails.application.routes.url_helpers.url_for(procedure.deliberation) if procedure.deliberation.attached?
|
||||
procedure.dossiers.visible_by_administration.count
|
||||
end
|
||||
|
||||
def state
|
||||
procedure.aasm.current_state
|
||||
end
|
||||
|
||||
def cadre_juridique
|
||||
delegate :description, :opendata, :tags, to: :procedure
|
||||
|
||||
def demarche_url
|
||||
procedure.lien_demarche
|
||||
end
|
||||
|
||||
def dpo_url
|
||||
procedure.lien_dpo
|
||||
end
|
||||
|
||||
def notice_url
|
||||
procedure.lien_notice
|
||||
end
|
||||
|
||||
def cadre_juridique_url
|
||||
procedure.cadre_juridique
|
||||
end
|
||||
|
||||
def site_web_url
|
||||
procedure.lien_site_web
|
||||
end
|
||||
|
||||
def number
|
||||
procedure.id
|
||||
end
|
||||
|
@ -65,10 +104,6 @@ Cela évite l’accès récursif aux dossiers."
|
|||
procedure.libelle
|
||||
end
|
||||
|
||||
def description
|
||||
procedure.description
|
||||
end
|
||||
|
||||
def declarative
|
||||
procedure.declarative_with_state
|
||||
end
|
||||
|
@ -93,15 +128,17 @@ Cela évite l’accès récursif aux dossiers."
|
|||
procedure.closed_at
|
||||
end
|
||||
|
||||
def self.authorized?(object, context)
|
||||
procedure = object.is_a?(ProcedureRevision) ? object.procedure : object
|
||||
procedure.opendata? || context.authorized_demarche?(procedure)
|
||||
def duree_conservation_dossiers
|
||||
procedure.duree_conservation_dossiers_dans_ds
|
||||
end
|
||||
|
||||
private
|
||||
def zones
|
||||
procedure.zones.map(&:current_label)
|
||||
end
|
||||
|
||||
def procedure
|
||||
revision.procedure
|
||||
def self.authorized?(object, context)
|
||||
procedure = object.is_a?(ProcedureRevision) ? object.procedure : object
|
||||
context.authorized_demarche?(procedure, opendata: true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -12,7 +12,11 @@ module Types
|
|||
end
|
||||
|
||||
def annotation_descriptors
|
||||
Loaders::Association.for(object.class, revision_types_de_champ_private: :type_de_champ).load(object)
|
||||
if context.authorized_demarche?(object.procedure, opendata: true)
|
||||
Loaders::Association.for(object.class, revision_types_de_champ_private: :type_de_champ).load(object)
|
||||
else
|
||||
[]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -303,16 +303,18 @@ class SerializerService
|
|||
}
|
||||
|
||||
fragment ChampDescriptorFragment on ChampDescriptor {
|
||||
type
|
||||
__typename
|
||||
label
|
||||
description
|
||||
required
|
||||
options
|
||||
champDescriptors {
|
||||
type
|
||||
label
|
||||
description
|
||||
required
|
||||
... on DropDownListChampDescriptor {
|
||||
options
|
||||
otherOption
|
||||
}
|
||||
... on MultipleDropDownListChampDescriptor {
|
||||
options
|
||||
}
|
||||
... on LinkedDropDownListChampDescriptor {
|
||||
options
|
||||
}
|
||||
}
|
||||
|
@ -321,13 +323,28 @@ class SerializerService
|
|||
number
|
||||
title
|
||||
description
|
||||
tags
|
||||
zones
|
||||
datePublication
|
||||
service { nom organisme typeOrganisme }
|
||||
cadreJuridique
|
||||
deliberation
|
||||
demarcheUrl
|
||||
dpoUrl
|
||||
noticeUrl
|
||||
siteWebUrl
|
||||
cadreJuridiqueUrl
|
||||
logo { ...FileFragment }
|
||||
notice { ...FileFragment }
|
||||
deliberation { ...FileFragment }
|
||||
dossiersCount
|
||||
revision {
|
||||
champDescriptors { ...ChampDescriptorFragment }
|
||||
champDescriptors {
|
||||
...ChampDescriptorFragment
|
||||
... on RepetitionChampDescriptor {
|
||||
champDescriptors {
|
||||
...ChampDescriptorFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
GRAPHQL
|
||||
|
|
|
@ -67,7 +67,7 @@ describe API::V2::GraphqlController do
|
|||
publishedRevision {
|
||||
id
|
||||
champDescriptors {
|
||||
type
|
||||
__typename
|
||||
}
|
||||
}
|
||||
service {
|
||||
|
@ -76,16 +76,26 @@ describe API::V2::GraphqlController do
|
|||
organisme
|
||||
}
|
||||
champDescriptors {
|
||||
__typename
|
||||
id
|
||||
type
|
||||
label
|
||||
description
|
||||
required
|
||||
champDescriptors {
|
||||
id
|
||||
type
|
||||
... on RepetitionChampDescriptor {
|
||||
champDescriptors {
|
||||
__typename
|
||||
id
|
||||
}
|
||||
}
|
||||
... on DropDownListChampDescriptor {
|
||||
options
|
||||
}
|
||||
... on MultipleDropDownListChampDescriptor {
|
||||
options
|
||||
}
|
||||
... on LinkedDropDownListChampDescriptor {
|
||||
options
|
||||
}
|
||||
options
|
||||
}
|
||||
dossiers {
|
||||
nodes {
|
||||
|
@ -157,9 +167,13 @@ describe API::V2::GraphqlController do
|
|||
describe "query a demarche" do
|
||||
let(:procedure) { create(:procedure, :published, :for_individual, :with_service, :with_all_champs, :with_all_annotations, administrateurs: [admin]) }
|
||||
|
||||
def format_type_champ(type_champ)
|
||||
"#{type_champ.gsub('regions', 'region').gsub('departements', 'departement').gsub('communes', 'commune').camelcase}ChampDescriptor"
|
||||
end
|
||||
|
||||
it "returns the demarche" do
|
||||
expect(gql_errors).to eq(nil)
|
||||
expect(gql_data).to eq(demarche: {
|
||||
expect(gql_data).to include(demarche: {
|
||||
id: procedure.to_typed_id,
|
||||
number: procedure.id,
|
||||
title: procedure.libelle,
|
||||
|
@ -174,15 +188,11 @@ describe API::V2::GraphqlController do
|
|||
label: "défaut"
|
||||
}
|
||||
],
|
||||
revisions: procedure.revisions.map { |revision| { id: revision.to_typed_id } },
|
||||
revisions: procedure.revisions.map { { id: _1.to_typed_id } },
|
||||
draftRevision: { id: procedure.draft_revision.to_typed_id },
|
||||
publishedRevision: {
|
||||
id: procedure.published_revision.to_typed_id,
|
||||
champDescriptors: procedure.published_revision.types_de_champ_public.map do |tdc|
|
||||
{
|
||||
type: tdc.type_champ
|
||||
}
|
||||
end
|
||||
champDescriptors: procedure.published_revision.types_de_champ_public.map { { __typename: format_type_champ(_1.type_champ) } }
|
||||
},
|
||||
service: {
|
||||
nom: procedure.service.nom,
|
||||
|
@ -193,15 +203,15 @@ describe API::V2::GraphqlController do
|
|||
{
|
||||
id: tdc.to_typed_id,
|
||||
label: tdc.libelle,
|
||||
type: tdc.type_champ,
|
||||
__typename: format_type_champ(tdc.type_champ),
|
||||
description: tdc.description,
|
||||
required: tdc.mandatory?,
|
||||
champDescriptors: tdc.repetition? ? procedure.active_revision.children_of(tdc.reload).map { |tdc| { id: tdc.to_typed_id, type: tdc.type_champ } } : nil,
|
||||
champDescriptors: tdc.repetition? ? procedure.active_revision.children_of(tdc.reload).map { { id: _1.to_typed_id, __typename: format_type_champ(_1.type_champ) } } : nil,
|
||||
options: tdc.drop_down_list? ? tdc.drop_down_list_options.reject(&:empty?) : nil
|
||||
}
|
||||
}.compact
|
||||
end,
|
||||
dossiers: {
|
||||
nodes: dossiers.map { |dossier| { id: dossier.to_typed_id } }
|
||||
nodes: dossiers.map { { id: _1.to_typed_id } }
|
||||
}
|
||||
})
|
||||
end
|
||||
|
|
|
@ -79,6 +79,16 @@ describe API::V2::GraphqlController do
|
|||
expect(gql_data[:demarche][:dossiers][:nodes].size).to eq(1)
|
||||
}
|
||||
end
|
||||
|
||||
context 'include Revision' do
|
||||
let(:variables) { { demarcheNumber: procedure.id, includeRevision: true } }
|
||||
|
||||
it {
|
||||
expect(gql_errors).to be_nil
|
||||
expect(gql_data[:demarche][:id]).to eq(procedure.to_typed_id)
|
||||
expect(gql_data[:demarche][:activeRevision]).not_to be_nil
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
context 'getGroupeInstructeur' do
|
||||
|
|
|
@ -5,9 +5,9 @@ FactoryBot.define do
|
|||
labels { [{ designated_on: '1981-05-08', name: "Ministère de l'Education Populaire" }] }
|
||||
end
|
||||
|
||||
after(:create) do |zone, evaluator|
|
||||
after(:build) do |zone, evaluator|
|
||||
evaluator.labels.each do |label|
|
||||
zone.labels.create(designated_on: label[:designated_on], name: label[:name])
|
||||
zone.labels.build(designated_on: label[:designated_on], name: label[:name])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
describe DemarchesPubliquesExportService do
|
||||
let(:procedure) { create(:procedure, :published, :with_service, :with_type_de_champ) }
|
||||
let!(:dossier) { create(:dossier, procedure: procedure) }
|
||||
let!(:dossier) { create(:dossier, :en_construction, procedure: procedure) }
|
||||
let(:gzip_filename) { "demarches.json.gz" }
|
||||
|
||||
after { FileUtils.rm(gzip_filename) }
|
||||
|
@ -16,19 +16,25 @@ describe DemarchesPubliquesExportService do
|
|||
organisme: "organisme",
|
||||
typeOrganisme: "association"
|
||||
},
|
||||
cadreJuridique: "un cadre juridique important",
|
||||
cadreJuridiqueUrl: "un cadre juridique important",
|
||||
demarcheUrl: nil,
|
||||
dpoUrl: nil,
|
||||
noticeUrl: nil,
|
||||
siteWebUrl: "https://mon-site.gouv",
|
||||
logo: nil,
|
||||
notice: nil,
|
||||
deliberation: nil,
|
||||
datePublication: procedure.published_at.iso8601,
|
||||
zones: ["Ministère de l'Education Populaire"],
|
||||
tags: [],
|
||||
dossiersCount: 1,
|
||||
revision: {
|
||||
champDescriptors: [
|
||||
{
|
||||
description: procedure.active_revision.types_de_champ_public.first.description,
|
||||
label: procedure.active_revision.types_de_champ_public.first.libelle,
|
||||
options: nil,
|
||||
required: false,
|
||||
type: "text",
|
||||
champDescriptors: nil
|
||||
__typename: "TextChampDescriptor"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue