commit
9df24b7168
21 changed files with 211 additions and 97 deletions
1
app/assets/images/icons/translate-icon.svg
Normal file
1
app/assets/images/icons/translate-icon.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 66 KiB |
|
@ -18,7 +18,8 @@ class ApplicationController < ActionController::Base
|
||||||
before_action :set_active_storage_host
|
before_action :set_active_storage_host
|
||||||
before_action :setup_javascript_settings
|
before_action :setup_javascript_settings
|
||||||
before_action :setup_tracking
|
before_action :setup_tracking
|
||||||
before_action :set_locale
|
|
||||||
|
around_action :switch_locale
|
||||||
|
|
||||||
helper_method :multiple_devise_profile_connect?, :instructeur_signed_in?, :current_instructeur, :current_expert, :expert_signed_in?,
|
helper_method :multiple_devise_profile_connect?, :instructeur_signed_in?, :current_instructeur, :current_expert, :expert_signed_in?,
|
||||||
:administrateur_signed_in?, :current_administrateur, :current_account
|
:administrateur_signed_in?, :current_administrateur, :current_account
|
||||||
|
@ -308,9 +309,15 @@ class ApplicationController < ActionController::Base
|
||||||
current_user&.email
|
current_user&.email
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_locale
|
def switch_locale(&action)
|
||||||
if ENV.fetch('LOCALIZATION_ENABLED', 'false') == 'true'
|
locale = nil
|
||||||
I18n.locale = http_accept_language.compatible_language_from(I18n.available_locales)
|
if cookies[:locale]
|
||||||
|
locale = cookies[:locale]
|
||||||
|
elsif ENV.fetch('LOCALIZATION_ENABLED', 'false') == 'true'
|
||||||
|
locale = http_accept_language.compatible_language_from(I18n.available_locales)
|
||||||
|
else
|
||||||
|
locale = I18n.default_locale
|
||||||
end
|
end
|
||||||
|
I18n.with_locale(locale, &action)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,12 +10,12 @@ class Champs::CarteController < ApplicationController
|
||||||
def create
|
def create
|
||||||
champ = policy_scope(Champ).find(params[:champ_id])
|
champ = policy_scope(Champ).find(params[:champ_id])
|
||||||
geo_area = if params_source == GeoArea.sources.fetch(:cadastre)
|
geo_area = if params_source == GeoArea.sources.fetch(:cadastre)
|
||||||
champ.geo_areas.find_by("properties->>'id' = :id", id: params_feature[:properties][:id])
|
champ.geo_areas.find_by("properties->>'id' = :id", id: create_params_feature[:properties][:id])
|
||||||
end
|
end
|
||||||
|
|
||||||
if geo_area.nil?
|
if geo_area.nil?
|
||||||
geo_area = champ.geo_areas.build(source: params_source, properties: {})
|
geo_area = champ.geo_areas.build(source: params_source, properties: {})
|
||||||
save_feature!(geo_area, params_feature)
|
save_feature!(geo_area, create_params_feature)
|
||||||
end
|
end
|
||||||
|
|
||||||
render json: { feature: geo_area.to_feature }, status: :created
|
render json: { feature: geo_area.to_feature }, status: :created
|
||||||
|
@ -24,7 +24,7 @@ class Champs::CarteController < ApplicationController
|
||||||
def update
|
def update
|
||||||
champ = policy_scope(Champ).find(params[:champ_id])
|
champ = policy_scope(Champ).find(params[:champ_id])
|
||||||
geo_area = champ.geo_areas.find(params[:id])
|
geo_area = champ.geo_areas.find(params[:id])
|
||||||
save_feature!(geo_area, params_feature)
|
save_feature!(geo_area, update_params_feature)
|
||||||
|
|
||||||
head :no_content
|
head :no_content
|
||||||
end
|
end
|
||||||
|
@ -42,7 +42,7 @@ class Champs::CarteController < ApplicationController
|
||||||
params[:source]
|
params[:source]
|
||||||
end
|
end
|
||||||
|
|
||||||
def params_feature
|
def create_params_feature
|
||||||
params.require(:feature).permit(properties: [
|
params.require(:feature).permit(properties: [
|
||||||
:filename,
|
:filename,
|
||||||
:description,
|
:description,
|
||||||
|
@ -60,6 +60,12 @@ class Champs::CarteController < ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def update_params_feature
|
||||||
|
params.require(:feature).permit(properties: [:description]).tap do |feature|
|
||||||
|
feature[:geometry] = params[:feature][:geometry]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def save_feature!(geo_area, feature)
|
def save_feature!(geo_area, feature)
|
||||||
if feature[:geometry]
|
if feature[:geometry]
|
||||||
geo_area.geometry = feature[:geometry]
|
geo_area.geometry = feature[:geometry]
|
||||||
|
|
|
@ -87,4 +87,9 @@ class RootController < ApplicationController
|
||||||
format.js { render js: helpers.remove_element('#outdated-browser-banner') }
|
format.js { render js: helpers.remove_element('#outdated-browser-banner') }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def save_locale
|
||||||
|
cookies[:locale] = params[:locale]
|
||||||
|
redirect_to request.referer
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1139,6 +1139,7 @@ type File {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface GeoArea {
|
interface GeoArea {
|
||||||
|
description: String
|
||||||
geometry: GeoJSON!
|
geometry: GeoJSON!
|
||||||
id: ID!
|
id: ID!
|
||||||
source: GeoAreaSource!
|
source: GeoAreaSource!
|
||||||
|
@ -1471,6 +1472,7 @@ type ParcelleCadastrale implements GeoArea {
|
||||||
codeCom: String! @deprecated(reason: "Utilisez le champ `commune` à la place.")
|
codeCom: String! @deprecated(reason: "Utilisez le champ `commune` à la place.")
|
||||||
codeDep: String! @deprecated(reason: "Utilisez le champ `commune` à la place.")
|
codeDep: String! @deprecated(reason: "Utilisez le champ `commune` à la place.")
|
||||||
commune: String!
|
commune: String!
|
||||||
|
description: String
|
||||||
feuille: Int! @deprecated(reason: "L‘information n‘est plus disponible.")
|
feuille: Int! @deprecated(reason: "L‘information n‘est plus disponible.")
|
||||||
geometry: GeoJSON!
|
geometry: GeoJSON!
|
||||||
id: ID!
|
id: ID!
|
||||||
|
@ -1590,7 +1592,7 @@ type Revision {
|
||||||
}
|
}
|
||||||
|
|
||||||
type SelectionUtilisateur implements GeoArea {
|
type SelectionUtilisateur implements GeoArea {
|
||||||
description: String!
|
description: String
|
||||||
geometry: GeoJSON!
|
geometry: GeoJSON!
|
||||||
id: ID!
|
id: ID!
|
||||||
source: GeoAreaSource!
|
source: GeoAreaSource!
|
||||||
|
|
|
@ -13,6 +13,7 @@ module Types
|
||||||
global_id_field :id
|
global_id_field :id
|
||||||
field :source, GeoAreaSource, null: false
|
field :source, GeoAreaSource, null: false
|
||||||
field :geometry, Types::GeoJSON, null: false, method: :safe_geometry
|
field :geometry, Types::GeoJSON, null: false, method: :safe_geometry
|
||||||
|
field :description, String, null: true
|
||||||
|
|
||||||
definition_methods do
|
definition_methods do
|
||||||
def resolve_type(object, context)
|
def resolve_type(object, context)
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
module Types::GeoAreas
|
module Types::GeoAreas
|
||||||
class SelectionUtilisateurType < Types::BaseObject
|
class SelectionUtilisateurType < Types::BaseObject
|
||||||
implements Types::GeoAreaType
|
implements Types::GeoAreaType
|
||||||
|
|
||||||
field :description, String, null: false
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -25,7 +25,7 @@ class Champ < ApplicationRecord
|
||||||
|
|
||||||
# We declare champ specific relationships (Champs::CarteChamp, Champs::SiretChamp and Champs::RepetitionChamp)
|
# We declare champ specific relationships (Champs::CarteChamp, Champs::SiretChamp and Champs::RepetitionChamp)
|
||||||
# here because otherwise we can't easily use includes in our queries.
|
# here because otherwise we can't easily use includes in our queries.
|
||||||
has_many :geo_areas, dependent: :destroy
|
has_many :geo_areas, -> { order(:created_at) }, dependent: :destroy, inverse_of: :champ
|
||||||
belongs_to :etablissement, optional: true, dependent: :destroy
|
belongs_to :etablissement, optional: true, dependent: :destroy
|
||||||
has_many :champs, -> { ordered }, foreign_key: :parent_id, inverse_of: :parent, dependent: :destroy
|
has_many :champs, -> { ordered }, foreign_key: :parent_id, inverse_of: :parent, dependent: :destroy
|
||||||
|
|
||||||
|
|
|
@ -196,12 +196,14 @@ module TagsSubstitutionConcern
|
||||||
tags.filter { |tag| tag[:available_for_states].include?(self.class::DOSSIER_STATE) }
|
tags.filter { |tag| tag[:available_for_states].include?(self.class::DOSSIER_STATE) }
|
||||||
end
|
end
|
||||||
|
|
||||||
def champ_public_tags
|
def champ_public_tags(dossier: nil)
|
||||||
types_de_champ_tags(procedure.types_de_champ, Dossier::SOUMIS)
|
types_de_champ = (dossier || procedure.active_revision).types_de_champ
|
||||||
|
types_de_champ_tags(types_de_champ, Dossier::SOUMIS)
|
||||||
end
|
end
|
||||||
|
|
||||||
def champ_private_tags
|
def champ_private_tags(dossier: nil)
|
||||||
types_de_champ_tags(procedure.types_de_champ_private, Dossier::INSTRUCTION_COMMENCEE)
|
types_de_champ = (dossier || procedure.active_revision).types_de_champ_private
|
||||||
|
types_de_champ_tags(types_de_champ, Dossier::INSTRUCTION_COMMENCEE)
|
||||||
end
|
end
|
||||||
|
|
||||||
def types_de_champ_tags(types_de_champ, available_for_states)
|
def types_de_champ_tags(types_de_champ, available_for_states)
|
||||||
|
@ -217,9 +219,11 @@ module TagsSubstitutionConcern
|
||||||
return ''
|
return ''
|
||||||
end
|
end
|
||||||
|
|
||||||
|
text = normalize_tags(text)
|
||||||
|
|
||||||
tags_and_datas = [
|
tags_and_datas = [
|
||||||
[champ_public_tags, dossier.champs],
|
[champ_public_tags(dossier: dossier), dossier.champs],
|
||||||
[champ_private_tags, dossier.champs_private],
|
[champ_private_tags(dossier: dossier), dossier.champs_private],
|
||||||
[dossier_tags, dossier],
|
[dossier_tags, dossier],
|
||||||
[ROUTAGE_TAGS, dossier],
|
[ROUTAGE_TAGS, dossier],
|
||||||
[INDIVIDUAL_TAGS, dossier.individual],
|
[INDIVIDUAL_TAGS, dossier.individual],
|
||||||
|
@ -242,7 +246,7 @@ module TagsSubstitutionConcern
|
||||||
end
|
end
|
||||||
|
|
||||||
def replace_tag(text, tag, data)
|
def replace_tag(text, tag, data)
|
||||||
libelle = Regexp.quote(tag[:libelle])
|
libelle = Regexp.quote(tag[:id].presence || tag[:libelle])
|
||||||
|
|
||||||
# allow any kind of space (non-breaking or other) in the tag’s libellé to match any kind of space in the template
|
# allow any kind of space (non-breaking or other) in the tag’s libellé to match any kind of space in the template
|
||||||
# (the '\\ |' is there because plain ASCII spaces were escaped by preceding Regexp.quote)
|
# (the '\\ |' is there because plain ASCII spaces were escaped by preceding Regexp.quote)
|
||||||
|
@ -256,4 +260,19 @@ module TagsSubstitutionConcern
|
||||||
|
|
||||||
text.gsub(/--#{libelle}--/, value.to_s)
|
text.gsub(/--#{libelle}--/, value.to_s)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def normalize_tags(text)
|
||||||
|
tags = types_de_champ_tags(procedure.types_de_champ_for_tags, Dossier::SOUMIS) + types_de_champ_tags(procedure.types_de_champ_private_for_tags, Dossier::INSTRUCTION_COMMENCEE)
|
||||||
|
filter_tags(tags).reduce(text) { |text, tag| normalize_tag(text, tag) }
|
||||||
|
end
|
||||||
|
|
||||||
|
def normalize_tag(text, tag)
|
||||||
|
libelle = Regexp.quote(tag[:libelle])
|
||||||
|
|
||||||
|
# allow any kind of space (non-breaking or other) in the tag’s libellé to match any kind of space in the template
|
||||||
|
# (the '\\ |' is there because plain ASCII spaces were escaped by preceding Regexp.quote)
|
||||||
|
libelle.gsub!(/\\ |[[:blank:]]/, "[[:blank:]]")
|
||||||
|
|
||||||
|
text.gsub(/--#{libelle}--/, "--#{tag[:id]}--")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -22,7 +22,7 @@ class GeoArea < ApplicationRecord
|
||||||
if value.is_a? String
|
if value.is_a? String
|
||||||
ActiveRecord::Coders::YAMLColumn.new(:properties).load(value)
|
ActiveRecord::Coders::YAMLColumn.new(:properties).load(value)
|
||||||
else
|
else
|
||||||
value
|
value || {}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -87,6 +87,30 @@ class Procedure < ApplicationRecord
|
||||||
brouillon? ? draft_types_de_champ_private : published_types_de_champ_private
|
brouillon? ? draft_types_de_champ_private : published_types_de_champ_private
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def types_de_champ_for_tags
|
||||||
|
if brouillon?
|
||||||
|
draft_types_de_champ
|
||||||
|
else
|
||||||
|
TypeDeChamp.root
|
||||||
|
.public_only
|
||||||
|
.where(revision: revisions - [draft_revision])
|
||||||
|
.order(:created_at)
|
||||||
|
.uniq
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def types_de_champ_private_for_tags
|
||||||
|
if brouillon?
|
||||||
|
draft_types_de_champ_private
|
||||||
|
else
|
||||||
|
TypeDeChamp.root
|
||||||
|
.private_only
|
||||||
|
.where(revision: revisions - [draft_revision])
|
||||||
|
.order(:created_at)
|
||||||
|
.uniq
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def types_de_champ_for_export
|
def types_de_champ_for_export
|
||||||
types_de_champ.reject(&:exclude_from_export?)
|
types_de_champ.reject(&:exclude_from_export?)
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,26 +6,24 @@ class TypesDeChamp::LinkedDropDownListTypeDeChamp < TypesDeChamp::TypeDeChampBas
|
||||||
|
|
||||||
def tags_for_template
|
def tags_for_template
|
||||||
tags = super
|
tags = super
|
||||||
tdc = @type_de_champ
|
stable_id = @type_de_champ.stable_id
|
||||||
tags.push(
|
tags.push(
|
||||||
{
|
{
|
||||||
libelle: "#{libelle}/primaire",
|
libelle: "#{libelle}/primaire",
|
||||||
|
id: "tdc#{stable_id}/primaire",
|
||||||
description: "#{description} (menu primaire)",
|
description: "#{description} (menu primaire)",
|
||||||
lambda: -> (champs) {
|
lambda: -> (champs) {
|
||||||
champs
|
champs.find { |champ| champ.stable_id == stable_id }&.primary_value
|
||||||
.find { |champ| champ.type_de_champ == tdc }
|
|
||||||
&.primary_value
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
tags.push(
|
tags.push(
|
||||||
{
|
{
|
||||||
libelle: "#{libelle}/secondaire",
|
libelle: "#{libelle}/secondaire",
|
||||||
|
id: "tdc#{stable_id}/secondaire",
|
||||||
description: "#{description} (menu secondaire)",
|
description: "#{description} (menu secondaire)",
|
||||||
lambda: -> (champs) {
|
lambda: -> (champs) {
|
||||||
champs
|
champs.find { |champ| champ.stable_id == stable_id }&.secondary_value
|
||||||
.find { |champ| champ.type_de_champ == tdc }
|
|
||||||
&.secondary_value
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -8,13 +8,14 @@ class TypesDeChamp::TypeDeChampBase
|
||||||
end
|
end
|
||||||
|
|
||||||
def tags_for_template
|
def tags_for_template
|
||||||
tdc = @type_de_champ
|
stable_id = @type_de_champ.stable_id
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
libelle: libelle,
|
libelle: libelle,
|
||||||
|
id: "tdc#{stable_id}",
|
||||||
description: description,
|
description: description,
|
||||||
lambda: -> (champs) {
|
lambda: -> (champs) {
|
||||||
champs.find { |champ| champ.type_de_champ == tdc }&.for_tag
|
champs.find { |champ| champ.stable_id == stable_id }&.for_tag
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -48,7 +48,9 @@ class SerializerService
|
||||||
query serializeChamp($number: Int!, $id: ID!) {
|
query serializeChamp($number: Int!, $id: ID!) {
|
||||||
dossier(number: $number) {
|
dossier(number: $number) {
|
||||||
champs(id: $id) {
|
champs(id: $id) {
|
||||||
...RootChampFragment
|
...ChampFragment
|
||||||
|
...RepetitionChampFragment
|
||||||
|
...CarteChampFragment
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,7 +58,9 @@ class SerializerService
|
||||||
query serializeAnnotation($number: Int!, $id: ID!) {
|
query serializeAnnotation($number: Int!, $id: ID!) {
|
||||||
dossier(number: $number) {
|
dossier(number: $number) {
|
||||||
annotations(id: $id) {
|
annotations(id: $id) {
|
||||||
...RootChampFragment
|
...ChampFragment
|
||||||
|
...RepetitionChampFragment
|
||||||
|
...CarteChampFragment
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,29 +81,28 @@ class SerializerService
|
||||||
label
|
label
|
||||||
}
|
}
|
||||||
champs {
|
champs {
|
||||||
...RootChampFragment
|
...ChampFragment
|
||||||
|
...RepetitionChampFragment
|
||||||
|
...CarteChampFragment
|
||||||
}
|
}
|
||||||
annotations {
|
annotations {
|
||||||
...RootChampFragment
|
...ChampFragment
|
||||||
|
...RepetitionChampFragment
|
||||||
|
...CarteChampFragment
|
||||||
}
|
}
|
||||||
avis {
|
avis {
|
||||||
...AvisFragment
|
...AvisFragment
|
||||||
}
|
}
|
||||||
demandeur {
|
demandeur {
|
||||||
... on PersonnePhysique {
|
...PersonnePhysiqueFragment
|
||||||
civilite
|
|
||||||
nom
|
|
||||||
prenom
|
|
||||||
dateDeNaissance
|
|
||||||
}
|
|
||||||
...PersonneMoraleFragment
|
...PersonneMoraleFragment
|
||||||
}
|
}
|
||||||
motivation
|
motivation
|
||||||
motivationAttachment {
|
motivationAttachment {
|
||||||
byteSize
|
...FileFragment
|
||||||
checksum
|
}
|
||||||
filename
|
revision {
|
||||||
contentType
|
id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,10 +119,7 @@ class SerializerService
|
||||||
email
|
email
|
||||||
}
|
}
|
||||||
attachment {
|
attachment {
|
||||||
byteSize
|
...FileFragment
|
||||||
checksum
|
|
||||||
filename
|
|
||||||
contentType
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,10 +141,7 @@ class SerializerService
|
||||||
}
|
}
|
||||||
... on PieceJustificativeChamp {
|
... on PieceJustificativeChamp {
|
||||||
file {
|
file {
|
||||||
byteSize
|
...FileFragment
|
||||||
checksum
|
|
||||||
filename
|
|
||||||
contentType
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
... on AddressChamp {
|
... on AddressChamp {
|
||||||
|
@ -154,33 +151,35 @@ class SerializerService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fragment RootChampFragment on Champ {
|
fragment RepetitionChampFragment on RepetitionChamp {
|
||||||
...ChampFragment
|
|
||||||
... on RepetitionChamp {
|
|
||||||
champs {
|
champs {
|
||||||
...ChampFragment
|
...ChampFragment
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
... on CarteChamp {
|
|
||||||
|
fragment CarteChampFragment on CarteChamp {
|
||||||
geoAreas {
|
geoAreas {
|
||||||
source
|
source
|
||||||
|
description
|
||||||
geometry {
|
geometry {
|
||||||
type
|
type
|
||||||
coordinates
|
coordinates
|
||||||
}
|
}
|
||||||
... on ParcelleCadastrale {
|
... on ParcelleCadastrale {
|
||||||
codeArr
|
prefixe
|
||||||
codeCom
|
|
||||||
codeDep
|
|
||||||
feuille
|
|
||||||
nomCom
|
|
||||||
numero
|
numero
|
||||||
|
commune
|
||||||
section
|
section
|
||||||
surfaceParcelle
|
surface
|
||||||
surfaceIntersection
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fragment PersonnePhysiqueFragment on PersonnePhysique {
|
||||||
|
civilite
|
||||||
|
nom
|
||||||
|
prenom
|
||||||
|
dateDeNaissance
|
||||||
}
|
}
|
||||||
|
|
||||||
fragment PersonneMoraleFragment on PersonneMorale {
|
fragment PersonneMoraleFragment on PersonneMorale {
|
||||||
|
@ -229,5 +228,12 @@ class SerializerService
|
||||||
regionName
|
regionName
|
||||||
regionCode
|
regionCode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fragment FileFragment on File {
|
||||||
|
filename
|
||||||
|
checksum
|
||||||
|
byteSize
|
||||||
|
contentType
|
||||||
|
}
|
||||||
GRAPHQL
|
GRAPHQL
|
||||||
end
|
end
|
||||||
|
|
|
@ -87,3 +87,7 @@
|
||||||
|
|
||||||
- else
|
- else
|
||||||
= render partial: 'shared/help/help_button'
|
= render partial: 'shared/help/help_button'
|
||||||
|
|
||||||
|
- if ENV.fetch('LOCALIZATION_ENABLED', 'false') == 'true'
|
||||||
|
%li
|
||||||
|
= render partial: 'layouts/locale_dropdown'
|
||||||
|
|
11
app/views/layouts/_locale_dropdown.html.haml
Normal file
11
app/views/layouts/_locale_dropdown.html.haml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
.dropdown.locale-dropdown
|
||||||
|
%button.button.dropdown-button.icon-only.header-menu-button{ title: "Translate", 'aria-expanded' => 'false', 'aria-controls' => 'locale_menu' }
|
||||||
|
.hidden Translate
|
||||||
|
= image_tag "icons/translate-icon.svg", alt: 'Translate', 'aria-hidden':'true'
|
||||||
|
%ul.header-menu.dropdown-content
|
||||||
|
%li
|
||||||
|
= link_to save_locale_path(locale: :en), method: :post, class: "menu-item menu-link" do
|
||||||
|
EN - English
|
||||||
|
%li
|
||||||
|
= link_to save_locale_path(locale: :fr), method: :post, class: "menu-item menu-link" do
|
||||||
|
FR - français
|
11
app/views/shared/champs/carte/_geo_area.html.haml
Normal file
11
app/views/shared/champs/carte/_geo_area.html.haml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
%li{ class: editing ? '' : 'flex column mb-2' }
|
||||||
|
- if editing
|
||||||
|
= link_to '#', data: { geo_area: geo_area.id } do
|
||||||
|
= geo_area_label(geo_area)
|
||||||
|
= text_field_tag :description, geo_area.description, data: { geo_area: geo_area.id }, placeholder: 'Description', class: 'no-margin'
|
||||||
|
- else
|
||||||
|
= link_to '#', data: { geo_area: geo_area.id } do
|
||||||
|
= geo_area_label(geo_area)
|
||||||
|
- if geo_area.description.present?
|
||||||
|
%span
|
||||||
|
= geo_area.description
|
|
@ -3,28 +3,11 @@
|
||||||
.areas
|
.areas
|
||||||
%ul
|
%ul
|
||||||
- champ.selections_utilisateur.each do |geo_area|
|
- champ.selections_utilisateur.each do |geo_area|
|
||||||
%li{ class: editing ? '' : 'flex column mb-2' }
|
= render partial: 'shared/champs/carte/geo_area', locals: { geo_area: geo_area, editing: editing }
|
||||||
- if editing
|
|
||||||
= link_to '#', data: { geo_area: geo_area.id } do
|
|
||||||
= geo_area_label(geo_area)
|
|
||||||
= text_field_tag :description, geo_area.description, data: { geo_area: geo_area.id }, placeholder: 'Description de la sélection', class: 'no-margin'
|
|
||||||
- else
|
|
||||||
= link_to '#', data: { geo_area: geo_area.id } do
|
|
||||||
= geo_area_label(geo_area)
|
|
||||||
- if geo_area.description.present?
|
|
||||||
%span
|
|
||||||
= geo_area.description
|
|
||||||
|
|
||||||
- if champ.cadastres?
|
- if champ.cadastres?
|
||||||
.areas-title Parcelles cadastrales
|
.areas-title Parcelles cadastrales
|
||||||
.areas
|
.areas
|
||||||
- if !champ.geometry?
|
|
||||||
Aucune zone tracée
|
|
||||||
- elsif champ.cadastres.blank?
|
|
||||||
= t('errors.messages.cadastres_empty', count: champ.selections_utilisateur.size)
|
|
||||||
- else
|
|
||||||
%ul
|
%ul
|
||||||
- champ.cadastres.each do |geo_area|
|
- champ.cadastres.each do |geo_area|
|
||||||
%li.flex.column.mb-2
|
= render partial: 'shared/champs/carte/geo_area', locals: { geo_area: geo_area, editing: editing }
|
||||||
= link_to '#', data: { geo_area: geo_area.id } do
|
|
||||||
= geo_area_label(geo_area)
|
|
||||||
|
|
|
@ -152,6 +152,7 @@ Rails.application.routes.draw do
|
||||||
get "patron" => "root#patron"
|
get "patron" => "root#patron"
|
||||||
get "suivi" => "root#suivi"
|
get "suivi" => "root#suivi"
|
||||||
post "dismiss_outdated_browser" => "root#dismiss_outdated_browser"
|
post "dismiss_outdated_browser" => "root#dismiss_outdated_browser"
|
||||||
|
post "save_locale" => "root#save_locale"
|
||||||
|
|
||||||
get "contact", to: "support#index"
|
get "contact", to: "support#index"
|
||||||
post "contact", to: "support#create"
|
post "contact", to: "support#create"
|
||||||
|
|
|
@ -8,6 +8,7 @@ describe TagsSubstitutionConcern, type: :model do
|
||||||
|
|
||||||
let(:procedure) do
|
let(:procedure) do
|
||||||
create(:procedure,
|
create(:procedure,
|
||||||
|
:published,
|
||||||
libelle: 'Une magnifique démarche',
|
libelle: 'Une magnifique démarche',
|
||||||
types_de_champ: types_de_champ,
|
types_de_champ: types_de_champ,
|
||||||
types_de_champ_private: types_de_champ_private,
|
types_de_champ_private: types_de_champ_private,
|
||||||
|
@ -389,6 +390,33 @@ describe TagsSubstitutionConcern, type: :model do
|
||||||
is_expected.to eq('--motivation-- --date de décision--')
|
is_expected.to eq('--motivation-- --date de décision--')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when procedure has revisions' do
|
||||||
|
let(:types_de_champ) { [build(:type_de_champ, libelle: 'mon ancien libellé')] }
|
||||||
|
let(:draft_type_de_champ) { procedure.draft_revision.find_or_clone_type_de_champ(types_de_champ[0].stable_id) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
draft_type_de_champ.update(libelle: 'mon nouveau libellé')
|
||||||
|
dossier.champs.first.update(value: 'valeur')
|
||||||
|
procedure.update!(draft_revision: procedure.create_new_revision, published_revision: procedure.draft_revision)
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when using the champ's original label" do
|
||||||
|
let(:template) { '--mon ancien libellé--' }
|
||||||
|
|
||||||
|
it "replaces the tag" do
|
||||||
|
is_expected.to eq('valeur')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when using the champ's revised label" do
|
||||||
|
let(:template) { '--mon nouveau libellé--' }
|
||||||
|
|
||||||
|
it "replaces the tag" do
|
||||||
|
is_expected.to eq('valeur')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'tags' do
|
describe 'tags' do
|
||||||
|
|
|
@ -100,4 +100,12 @@ RSpec.describe GeoArea, type: :model do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'description' do
|
||||||
|
context 'when properties is nil' do
|
||||||
|
let(:geo_area) { build(:geo_area, properties: nil) }
|
||||||
|
|
||||||
|
it { expect(geo_area.description).to be_nil }
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue