Merge pull request #10137 from colinux/faqs

Internalisation de la FAQ
This commit is contained in:
Colin Darie 2024-05-16 11:16:19 +00:00 committed by GitHub
commit b74319b3ee
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
144 changed files with 2044 additions and 71 deletions

View file

@ -37,6 +37,7 @@ gem 'flipper'
gem 'flipper-active_record'
gem 'flipper-active_support_cache_store'
gem 'flipper-ui'
gem 'front_matter_parser'
gem 'fugit'
gem 'geocoder'
gem 'geo_coord', require: "geo/coord"

View file

@ -278,6 +278,7 @@ GEM
fog-core (~> 2.1)
fog-json (>= 1.0)
formatador (1.1.0)
front_matter_parser (1.0.1)
fugit (1.10.1)
et-orbi (~> 1, >= 1.2.7)
raabro (~> 1.4)
@ -923,6 +924,7 @@ DEPENDENCIES
flipper-active_record
flipper-active_support_cache_store
flipper-ui
front_matter_parser
fugit
geo_coord
geocoder

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View file

@ -0,0 +1,20 @@
.markdown-content {
img {
max-width: 100%;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
display: block;
// In markdown img are always wrapped in p,
// which already contains vertical margin.
// We only add margin when there are siblings.
// NOTE: CSS consider the img is only-child even
// when there are only text node siblings, but it's still fine for us.
margin: 1.5rem auto;
&:only-child {
margin-top: 0;
margin-bottom: 0;
}
}
}

View file

@ -339,7 +339,7 @@ class ApplicationController < ActionController::Base
environment: sentry[:environment],
browser: { modern: BrowserSupport.supported?(browser) },
user: sentry_user,
release: SentryRelease.current
release: ApplicationVersion.current
}
end

View file

@ -0,0 +1,39 @@
# frozen_string_literal: true
class FAQController < ApplicationController
before_action :load_faq_data, only: :show
def index
@faqs = loader_service.all
end
def show
@renderer = Redcarpet::Markdown.new(Redcarpet::TrustedRenderer.new(view_context), autolink: true)
@siblings = loader_service.faqs_for_category(@metadata[:category])
end
private
def loader_service
@loader_service ||= begin
substitutions = {
application_base_url: Current.application_base_url,
application_name: Current.application_name,
contact_email: Current.contact_email
}
FAQsLoaderService.new(substitutions)
end
end
def load_faq_data
path = "#{params[:category]}/#{params[:slug]}"
faq_data = loader_service.find(path)
@content = faq_data.content
@metadata = faq_data.front_matter.symbolize_keys
rescue KeyError
raise ActionController::RoutingError.new("FAQ not found: #{path}")
end
end

View file

@ -33,7 +33,7 @@ module Redcarpet
when :url
link(link, nil, link)
when :email
# NOTE: As of Redcarpet 3.6.0, autolinking email containing is broken https://github.com/vmg/redcarpet/issues/402
# NOTE: As of Redcarpet 3.6.0, autolinking email containing underscore is broken https://github.com/vmg/redcarpet/issues/402
content_tag(:a, link, { href: "mailto:#{link}" })
else
link

View file

@ -0,0 +1,41 @@
module Redcarpet
class TrustedRenderer < Redcarpet::Render::HTML
include ActionView::Helpers::TagHelper
include Sprockets::Rails::Helper
include ApplicationHelper
attr_reader :view_context
def initialize(view_context, extensions = {})
@view_context = view_context
super extensions
end
def link(href, title, content)
html_options = {
href: href
}
unless href.starts_with?('/')
html_options.merge!(title: new_tab_suffix(title), **external_link_attributes)
end
content_tag(:a, content, html_options, false)
end
def autolink(link, link_type)
case link_type
when :url
link(link, nil, link)
when :email
# NOTE: As of Redcarpet 3.6.0, autolinking email containing underscore is broken https://github.com/vmg/redcarpet/issues/402
content_tag(:a, link, { href: "mailto:#{link}" })
end
end
def image(link, title, alt)
view_context.image_tag(link, title:, alt:, loading: :lazy)
end
end
end

View file

@ -0,0 +1,63 @@
# frozen_string_literal: true
class FAQsLoaderService
PATH = Rails.root.join('doc', 'faqs').freeze
ORDER = ['usager', 'instructeur', 'administrateur'].freeze
attr_reader :substitutions
def initialize(substitutions)
@substitutions = substitutions
@faqs_by_path ||= Rails.cache.fetch(["faqs_data", ApplicationVersion.current, substitutions], expires_in: 1.week) do
load_faqs
end
end
def find(path)
Rails.cache.fetch(["faq", path, ApplicationVersion.current, substitutions], expires_in: 1.week) do
file_path = @faqs_by_path.fetch(path).fetch(:file_path)
parse_with_substitutions(file_path)
end
end
def faqs_for_category(category)
@faqs_by_path.values
.filter { |faq| faq[:category] == category }
.group_by { |faq| faq[:subcategory] }
end
def all
@faqs_by_path.values
.group_by { |faq| faq.fetch(:category) }
.sort_by { |category, _| ORDER.index(category) || ORDER.size }
.to_h
.transform_values do |faqs|
faqs.group_by { |faq| faq.fetch(:subcategory) }
end
end
private
def load_faqs
Dir.glob("#{PATH}/**/*.md").each_with_object({}) do |file_path, faqs_by_path|
parsed = parse_with_substitutions(file_path)
front_matter = parsed.front_matter.symbolize_keys
faq_data = front_matter.slice(:slug, :title, :category, :subcategory, :locale, :keywords).merge(file_path: file_path)
path = front_matter.fetch(:category) + '/' + front_matter.fetch(:slug)
faqs_by_path[path] = faq_data
end
end
# Substitute all string before front matter parser so metadata are also substituted.
# using standard ruby formatting, ie => `%{my_var} % { my_var: 'value' }`
# We have to escape % chars not used for substitutions, ie. not preceeded by {
def parse_with_substitutions(file_path)
substituted_content = File.read(file_path).gsub(/%(?!{)/, '%%') % substitutions
FrontMatterParser::Parser.new(:md).call(substituted_content)
end
end

View file

@ -35,7 +35,7 @@
- else
%p.fr-mb-1w
= t('more_info_on_test', scope: [:layouts, :breadcrumb])
= link_to t('go_to_FAQ', scope: [:layouts, :breadcrumb]), t("url_FAQ", scope: [:layouts, :breadcrumb]), title: new_tab_suffix(t('go_to_FAQ', scope: [:layouts, :breadcrumb])), **external_link_attributes
= link_to t('go_to_FAQ', scope: [:layouts, :breadcrumb]), t("url_FAQ", scope: [:layouts, :breadcrumb]), title: new_tab_suffix(t('go_to_FAQ', scope: [:layouts, :breadcrumb]))
.flex
%span.fr-badge.fr-badge--new.fr-mr-1w
= t('draft', scope: [:layouts, :breadcrumb])

View file

@ -16,7 +16,7 @@
- c.with_body do
%p
= t('.faq_test_alert')
= link_to t('.faq_test_alert_link'), t('.faq_test_alert_link_url'), **external_link_attributes
= link_to t('.faq_test_alert_link'), t('.faq_test_alert_link_url')
= render partial: 'publication_form_inputs', locals: { procedure: procedure, closed_procedures: @closed_procedures, form: f }
= render Dsfr::CalloutComponent.new(title: t('.dpd_title'), heading_level: 'h2') do |c|
- c.with_body do

View file

@ -0,0 +1,13 @@
%nav.fr-breadcrumb{ role: "navigation", 'aria-label': t('you_are_here', scope: [:layouts, :breadcrumb]) }
%button.fr-breadcrumb__button{ 'aria-expanded' => "false", 'aria-controls' => "breadcrumb-1" }
= t('show', scope: [:layouts, :breadcrumb])
.fr-collapse#breadcrumb-1
%ol.fr-breadcrumb__list
%li= link_to t('root', scope: [:layouts, :breadcrumb]), root_path, class: 'fr-breadcrumb__link'
%li
%a.fr-breadcrumb__link{ **(defined?(faq_title) ? { href: faq_index_path } : { "aria-current": "page" }) }= t('faq', scope: [:layouts, :breadcrumb])
- if defined?(faq_title)
%li
%a.fr-breadcrumb__link{ 'aria-current' => "page" }= faq_title

View file

@ -0,0 +1,20 @@
%nav.fr-sidemenu.fr-sidemenu--sticky{ role: "navigation", 'aria-labelledby': "fr-sidemenu-title" }
.fr-sidemenu__inner
%button.fr-sidemenu__btn{ 'aria-controls': "fr-sidemenu-wrapper", 'aria-expanded': "false" }
= t(:sidebar_button, scope: [:faq])
.fr-collapse#fr-sidemenu-wrapper
.fr-sidemenu__title#fr-sidemenu-title
= t(:name, scope: [:faq, :categories, current[:category]])
%ul.fr-sidemenu__list
- faqs.each_with_index do |(subcategory, faqs), index|
%li{ class: class_names("fr-sidemenu__item", "fr-sidemenu__item--active" => subcategory == current[:subcategory]) }
%button.fr-sidemenu__btn{ aria: { 'expanded': subcategory == current[:subcategory] ? "true" : "false",
'controls': "fr-sidemenu-item-#{index}",
'current' => subcategory == current[:subcategory] ? "true" : nil } }
= t(:name, scope: [:faq, :subcategories, subcategory])
.fr-collapse{ id: "fr-sidemenu-item-#{index}" }
%ul.fr-sidemenu__list
- faqs.each do |faq|
%li{ class: class_names("fr-sidemenu__item", "fr-sidemenu__item--active" => faq[:slug] == current[:slug]) }
= link_to faq[:title], faq_path(category: faq[:category], slug: faq[:slug]),
class: 'fr-sidemenu__link', target: "_self", "aria-current" => current[:slug] == faq[:slug] ? "page" : nil

View file

@ -0,0 +1,26 @@
- content_for(:title, t('.meta_title'))
.fr-container.fr-my-4w
= render partial: "breadcrumb"
.fr-grid-row
.fr-col-12.fr-col-md-10
%h1= t('.title', app_name: Current.application_name)
- @faqs.each do |category, subcategories|
%h2= t(:name, scope: [:faq, :categories, category], raise: true) # i18n-tasks-use t("faq.categories.#{category}.name")
%p= t(:description, scope: [:faq, :categories, category], raise: true) # i18n-tasks-use t("faq.categories.#{category}.description")
.fr-accordions-group.fr-mb-6w
- subcategories.each_with_index do |(subcategory, faqs), index|
%section.fr-accordion
%h3.fr-accordion__title
%button.fr-accordion__btn{ 'aria-expanded': "false", 'aria-controls': "accordion-#{category}-#{index}" }
= t(:name, scope: [:faq, :subcategories, subcategory], raise: true) # i18n-tasks-use t("faq.subcategories.#{subcategory}.name")
.fr-collapse{ id: "accordion-#{category}-#{index}" }
- description = t(:description, scope: [:faq, :subcategories, subcategory], default: nil) # i18n-tasks-use t("faq.subcategories.#{subcategory}.description")
%p= description if description.present?
%ul
- faqs.each do |faq|
%li= link_to faq[:title], faq_path(category: faq[:category], slug: faq[:slug]), class: "fr-link"

View file

@ -0,0 +1,13 @@
- content_for(:title, @metadata[:title])
.fr-container.fr-my-4w
.fr-grid-row
.fr-col-12.fr-col-md-4
= render partial: "sidebar", locals: { faqs: @siblings, current: @metadata }
.fr-col-12.fr-col-md-8
-# i18n-tasks-use t("faq.categories.#{@metadata[:category]}.short_name")
= render partial: "breadcrumb", locals: { faq_title: "#{t(:short_name, scope: [:faq, :categories, @metadata[:category]])} : #{@metadata[:title]}" }
.markdown-content
= @renderer.render(@content).html_safe

View file

@ -52,7 +52,7 @@
= render partial: 'shared/help/help_dropdown_instructeur'
- else
// NB: on mobile in order to have links correctly aligned, we need a left icon
= link_to t('help'), t("links.common.faq.url"), class: 'fr-btn dropdown-button', title: new_tab_suffix(t('help')), **external_link_attributes
= link_to t('help'), t("links.common.faq.url"), class: 'fr-btn dropdown-button', title: t('help')

View file

@ -7,4 +7,4 @@
%p= t('.line3')
%hr
%p.small-simple= t('.are_you_new', app_name: Current.application_name)
= link_to t('views.users.sessions.new.find_procedure'), t("links.common.faq.comment_trouver_ma_demarche_url"), title: new_tab_suffix(t('views.users.sessions.new.find_procedure')), class: "fr-btn fr-btn--secondary", **external_link_attributes
= link_to t('views.users.sessions.new.find_procedure'), t("links.common.faq.comment_trouver_ma_demarche_url"), title: new_tab_suffix(t('views.users.sessions.new.find_procedure')), class: "fr-btn fr-btn--secondary"

View file

@ -23,7 +23,7 @@
%h2= t(".have_a_procedure")
%p.fr-h5= t(".fill_procedure")
= link_to t(".how_to_find_procedure"), t("links.common.faq.comment_trouver_ma_demarche_url"), class: "fr-btn fr-btn--lg fr-mr-1w fr-mb-2w", title: new_tab_suffix(t(".how_to_find_procedure")), **external_link_attributes
= link_to t(".how_to_find_procedure"), t("links.common.faq.comment_trouver_ma_demarche_url"), class: "fr-btn fr-btn--lg fr-mr-1w fr-mb-2w", title: new_tab_suffix(t(".how_to_find_procedure"))
= link_to t("views.users.sessions.new.connection"), new_user_session_path, class: "fr-btn fr-btn--secondary fr-btn--lg"
.fr-py-6w
@ -51,7 +51,7 @@
%h2= t(".question")
%p.fr-h5= t(".answer_in_faq")
%div
= link_to t(".online_help"), t("links.common.faq.url"), class: "fr-btn fr-btn--lg", title: new_tab_suffix(t(".online_help")), **external_link_attributes
= link_to t(".online_help"), t("links.common.faq.url"), class: "fr-btn fr-btn--lg", title: t(".online_help")
.fr-py-6w
.container

View file

@ -8,7 +8,7 @@
- when :not_found
%p.fr-error-text
Nous navons pas trouvé détablissement correspondant à ce numéro de SIRET.
= link_to('Plus dinformations', t("links.common.faq.erreur_siret_url"), **external_link_attributes)
= link_to('Plus dinformations', t("links.common.faq.erreur_siret_url"))
- when :network_error
%p.fr-error-text= t('errors.messages.siret_network_error')

View file

@ -95,10 +95,10 @@
= t("views.accessibility_statement.preparation.page_six")
%li
= link_to t("views.accessibility_statement.preparation.page_seven.label"), t("views.accessibility_statement.preparation.page_seven.url"),
title: t("views.accessibility_statement.preparation.page_seven.title"), **external_link_attributes
title: t("views.accessibility_statement.preparation.page_seven.title")
%li
= link_to t("views.accessibility_statement.preparation.page_eight.label"), t("views.accessibility_statement.preparation.page_eight.url"),
title: t("views.accessibility_statement.preparation.page_eight.title"), **external_link_attributes
title: t("views.accessibility_statement.preparation.page_eight.title")
%li
= t("views.accessibility_statement.preparation.page_nine")
%li

View file

@ -131,4 +131,4 @@
%p.empty-text-details
= t('views.users.dossiers.dossiers_list.no_result_text_html', app_base: Current.application_base_url)
%p
= link_to t("root.landing.how_to_find_procedure"), t("links.common.faq.comment_trouver_ma_demarche_url"), class: "fr-btn fr-btn--lg fr-mr-1w fr-mb-2w", **external_link_attributes
= link_to t("root.landing.how_to_find_procedure"), t("links.common.faq.comment_trouver_ma_demarche_url"), class: "fr-btn fr-btn--lg fr-mr-1w fr-mb-2w"

View file

@ -24,6 +24,6 @@
%section
%p.fr-mt-3w
Si vous voyez cette page trop souvent, consultez notre aide : #{link_to t("links.common.faq.confirmer_compte_chaque_connexion_url"), t("links.common.faq.confirmer_compte_chaque_connexion_url"), **external_link_attributes}
Si vous voyez cette page trop souvent, #{link_to "consultez notre aide", t("links.common.faq.confirmer_compte_chaque_connexion_url")}
%p.fr-mt-3w
= t('views.users.shared.contact_us_if_any_trouble_html', href: contact_admin_url)

View file

@ -15,7 +15,7 @@
"type": "controller",
"class": "Users::DossiersController",
"method": "merci",
"line": 302,
"line": 309,
"file": "app/controllers/users/dossiers_controller.rb",
"rendered": {
"name": "users/dossiers/merci",
@ -67,6 +67,40 @@
],
"note": ""
},
{
"warning_type": "Cross-Site Scripting",
"warning_code": 2,
"fingerprint": "a7d18cc3434b4428a884f1217791f9a9db67839e73fb499f1ccd0f686f08eccc",
"check_name": "CrossSiteScripting",
"message": "Unescaped parameter value",
"file": "app/views/faq/show.html.haml",
"line": 12,
"link": "https://brakemanscanner.org/docs/warning_types/cross_site_scripting",
"code": "Redcarpet::Markdown.new(Redcarpet::TrustedRenderer.new(view_context), :autolink => true).render(loader_service.find(\"#{params[:category]}/#{params[:slug]}\").content)",
"render_path": [
{
"type": "controller",
"class": "FAQController",
"method": "show",
"line": 14,
"file": "app/controllers/faq_controller.rb",
"rendered": {
"name": "faq/show",
"file": "app/views/faq/show.html.haml"
}
}
],
"location": {
"type": "template",
"template": "faq/show"
},
"user_input": "params[:category]",
"confidence": "Weak",
"cwe_id": [
79
],
"note": "Theses params are not rendered"
},
{
"warning_type": "SQL Injection",
"warning_code": 0,
@ -153,7 +187,7 @@
"check_name": "CrossSiteScripting",
"message": "Unescaped model attribute",
"file": "app/views/notification_mailer/send_notification_for_tiers.html.haml",
"line": 29,
"line": 31,
"link": "https://brakemanscanner.org/docs/warning_types/cross_site_scripting",
"code": "Current.application_name.gsub(\".\", \"&#8288;.\")",
"render_path": null,
@ -169,6 +203,6 @@
"note": "Current is not a model"
}
],
"updated": "2024-03-27 17:15:54 +0100",
"updated": "2024-04-23 18:27:12 +0200",
"brakeman_version": "6.1.2"
}

View file

@ -0,0 +1,19 @@
# frozen_string_literal: true
class ApplicationVersion
@@current = nil
# Detect the current release version, which helps Sentry identifying the current release
# or can be used as cache key when for some contents susceptible to change between releases.
#
# The deploy process can write a "version" file at root
# containing a string identifying the release, like the sha256 commit used by its release.
# It defaults to a random string if the file is not found (so each restart will behave like a new version)
def self.current
@@current ||= begin
version = Rails.root.join('version')
version.readable? ? version.read.strip : SecureRandom.hex
end
@@current.presence
end
end

View file

@ -18,6 +18,8 @@ ActiveSupport::Inflector.inflections(:en) do |inflect|
inflect.acronym 'URL'
inflect.acronym 'SVA'
inflect.acronym 'SVR'
inflect.acronym 'FAQ'
inflect.acronym 'FAQs'
inflect.irregular 'type_de_champ', 'types_de_champ'
inflect.irregular 'type_de_champ_private', 'types_de_champ_private'
inflect.irregular 'procedure_revision_type_de_champ', 'procedure_revision_types_de_champ'

View file

@ -1,15 +1,3 @@
class SentryRelease
@@current = nil
def self.current
@@current ||= begin
version = Rails.root.join('version')
version.readable? ? version.read.strip : ''
end
@@current.presence
end
end
Sentry.init do |config|
secrets = Rails.application.secrets.sentry
@ -19,7 +7,7 @@ Sentry.init do |config|
config.dsn = secrets[:enabled] ? secrets[:rails_client_key] : nil
config.send_default_pii = false
config.release = SentryRelease.current
config.release = ApplicationVersion.current
config.environment = secrets[:environment] || Rails.env
config.enabled_environments = ['production', secrets[:environment].presence].compact
config.breadcrumbs_logger = [:active_support_logger]

View file

@ -174,12 +174,12 @@ en:
page_six: "Home page - User search results"
page_seven:
label: "FAQ"
url: "https://faq.demarches-simplifiees.fr/"
url: "/faq"
title: "FAQ - new tab"
page_eight:
label: "FAQ - User (submission of a file)"
url: "https://faq.demarches-simplifiees.fr/collection/17-usager-depot-dun-dossier"
title: "FAQ - User (submission of a file) - new tab"
url: "/faq#accordion-usager-0"
title: "FAQ - User (submission of a file)"
page_nine: "Documentation - Presentation"
page_ten: "Documentation - Start-up"
page_eleven: "Documentation - General"

View file

@ -0,0 +1,46 @@
en:
faq:
index:
meta_title: "Frequently Asked Questions"
title: Frequently Asked Questions (FAQ) of %{app_name}
sidebar_button: In this FAQ
categories:
usager:
short_name: User
name: User (file application)
description: Help users submit and follow up on files, including resolving common problems.
instructeur:
short_name: Instructor
name: Instructor (file processing)
description: For instructors on accessing and managing files.
administrateur:
short_name: Administrator
name: Administrator (form creation)
description: Information for administrators on configuring the platform or creating procedures.
subcategories:
dossier_technical_issue:
name: I'm encountering a technical problem with my file
find_dossier:
name: I want to find my file
description: What if I can't find my file?
fill_dossier:
name: I want to make a
dossier_state:
name: I want to follow the progress of my application
account:
name: Manage my account
instructeur_account:
name: Login to my account
instruction:
name: Instruction
create_procedure:
name: I want to create an online procedure
description: How do you create a new procedure?
general:
name: General
administrateur_departure:
name: I'm leaving my job
description: Good practices to anticipate before my departure
procedure_test:
name: How to test my form
description: How do you test a new procedure?

View file

@ -0,0 +1,46 @@
fr:
faq:
index:
meta_title: "Foire aux Questions"
title: Foire aux Questions (FAQ) de %{app_name}
sidebar_button: Dans cette Foire Aux Questions
categories:
usager:
short_name: Usager
name: Usager (dépôt dun dossier)
description: Aide pour les usagers sur la soumission et le suivi des dossiers, incluant la résolution des problèmes courants.
instructeur:
short_name: Instructeur
name: Instructeur (traitement des dossiers)
description: À destination des instructeurs sur laccès et la gestion des dossiers.
administrateur:
short_name: Administrateur
name: Administrateur (création dun formulaire)
description: Informations pour les administrateurs sur la configuration de la plateforme ou la création de démarches.
subcategories:
dossier_technical_issue:
name: Je rencontre un problème technique avec ma démarche
find_dossier:
name: Je veux retrouver mon dossier
description: Quelles sont les solutions si je ne retrouve pas mon dossier ?
fill_dossier:
name: Je veux faire une démarche
dossier_state:
name: Je veux suivre linstruction de ma démarche
account:
name: Gestion de mon compte
instructeur_account:
name: Connexion à mon espace
instruction:
name: Instruction
create_procedure:
name: Je veux créer une démarche en ligne
description: Comment créer une nouvelle démarche ?
general:
name: Général
administrateur_departure:
name: Je quitte mon poste
description: Les bonnes pratiques à anticiper avant mon départ
procedure_test:
name: Comment tester ma démarche
description: Comment tester une nouvelle demarche ?

View file

@ -170,12 +170,12 @@ fr:
page_six: "Accueil connecté - Résultats de recherche usager"
page_seven:
label: "FAQ"
url: "https://faq.demarches-simplifiees.fr/"
url: "/faq"
title: "FAQ - nouvel onglet"
page_eight:
label: "FAQ - Usager (dépôt d'un dossier)"
url: "https://faq.demarches-simplifiees.fr/collection/17-usager-depot-dun-dossier"
title: "FAQ - Usager (dépôt d'un dossier) - nouvel onglet"
url: "/faq#accordion-usager-0"
title: "FAQ - Usager (dépôt d'un dossier)"
page_nine: "Documentation - Présentation"
page_ten: "Documentation - Démarrage"
page_eleven: "Documentation - Généralités"

View file

@ -6,14 +6,13 @@ en:
faq:
label: "FAQ"
title: "Frequently Asked Questions"
url: "https://faq.demarches-simplifiees.fr"
autosave_url: "https://faq.demarches-simplifiees.fr/article/77-enregistrer-mon-formulaire-pour-le-reprendre-plus-tard?preview=5ec28ca1042863474d1aee00"
comment_trouver_ma_demarche_url: "https://faq.demarches-simplifiees.fr/article/59-comment-trouver-ma-demarche"
confirmer_compte_chaque_connexion_url: "https://faq.demarches-simplifiees.fr/article/34-je-dois-confirmer-mon-compte-a-chaque-connexion"
contacter_service_en_charge_url: "https://faq.demarches-simplifiees.fr/article/12-contacter-le-service-en-charge-de-ma-demarche"
email_non_recu_url: "https://faq.demarches-simplifiees.fr/article/79-je-ne-recois-pas-demail"
erreur_siret_url: "https://faq.demarches-simplifiees.fr/article/4-erreur-siret"
ou_en_est_mon_dossier_url: "https://faq.demarches-simplifiees.fr/article/11-je-veux-savoir-ou-en-est-linstruction-de-ma-demarche"
url: "/faq"
autosave_url: "/faq/usager/je-veux-enregistrer-mon-formulaire-pour-le-reprendre-plus-tard"
comment_trouver_ma_demarche_url: "/faq/usager/comment-trouver-ma-demarche"
confirmer_compte_chaque_connexion_url: "/faq/instructeur/je-dois-confirmer-mon-compte-a-chaque-connexion"
contacter_service_en_charge_url: "/faq/usager/je-veux-contacter-le-service-en-charge-de-ma-demarche"
erreur_siret_url: "/faq/usager/erreur-siret-lors-d-un-depot-de-dossier"
ou_en_est_mon_dossier_url: "/faq/usager/je-veux-savoir-ou-en-est-l-instruction-de-ma-demarche"
footer:
top_labels:
hidden_title: Useful links

View file

@ -8,14 +8,13 @@ fr:
faq:
label: "FAQ"
title: "Foire aux Questions"
url: "https://faq.demarches-simplifiees.fr"
autosave_url: "https://faq.demarches-simplifiees.fr/article/77-enregistrer-mon-formulaire-pour-le-reprendre-plus-tard?preview=5ec28ca1042863474d1aee00"
comment_trouver_ma_demarche_url: "https://faq.demarches-simplifiees.fr/article/59-comment-trouver-ma-demarche"
confirmer_compte_chaque_connexion_url: "https://faq.demarches-simplifiees.fr/article/34-je-dois-confirmer-mon-compte-a-chaque-connexion"
contacter_service_en_charge_url: "https://faq.demarches-simplifiees.fr/article/12-contacter-le-service-en-charge-de-ma-demarche"
email_non_recu_url: "https://faq.demarches-simplifiees.fr/article/79-je-ne-recois-pas-demail"
erreur_siret_url: "https://faq.demarches-simplifiees.fr/article/4-erreur-siret"
ou_en_est_mon_dossier_url: "https://faq.demarches-simplifiees.fr/article/11-je-veux-savoir-ou-en-est-linstruction-de-ma-demarche"
url: "/faq"
autosave_url: "/faq/usager/je-veux-enregistrer-mon-formulaire-pour-le-reprendre-plus-tard"
comment_trouver_ma_demarche_url: "/faq/usager/comment-trouver-ma-demarche"
confirmer_compte_chaque_connexion_url: "/faq/instructeur/je-dois-confirmer-mon-compte-a-chaque-connexion"
contacter_service_en_charge_url: "/faq/usager/je-veux-contacter-le-service-en-charge-de-ma-demarche"
erreur_siret_url: "/faq/usager/erreur-siret-lors-d-un-depot-de-dossier"
ou_en_est_mon_dossier_url: "/faq/usager/je-veux-savoir-ou-en-est-l-instruction-de-ma-demarche"
footer:
top_labels:
hidden_title: Liens pratiques

View file

@ -58,7 +58,7 @@ en:
publication_form:
faq_test_alert: Have you thought about testing your procedure before publishing it? To help you in this test phase, you can
faq_test_alert_link: consult our best practices guide.
faq_test_alert_link_url: "https://faq.demarches-simplifiees.fr/category/49-comment-tester-ma-demarche"
faq_test_alert_link_url: "/faq#accordion-administrateur-2"
draft_changed_procedure_alert: "Publish a new version of your procedure. The following changes will be applied:"
dpd_title: Before publishing
dpd_part_1: Have you thought about informing your Personal Data Protection Officer (DPO).

View file

@ -58,7 +58,7 @@ fr:
publication_form:
faq_test_alert: Avez-vous bien pensé à tester votre démarche avant de la publier ? Pour vous aider dans cette phase de test, vous pouvez
faq_test_alert_link: consulter notre guide de bonnes pratiques.
faq_test_alert_link_url: "https://faq.demarches-simplifiees.fr/category/49-comment-tester-ma-demarche"
faq_test_alert_link_url: "/faq#accordion-administrateur-2"
draft_changed_procedure_alert: "Publiez une nouvelle version de votre démarche. Les modifications suivantes seront appliquées :"
dpd_title: Avant de publier
dpd_part_1: Avez-vous bien pensé à informer votre Délégué à la Protection des Données personnelles (DPD).

View file

@ -15,4 +15,5 @@ en:
draft: "Draft"
more_info_on_test: "For more information on test stage"
go_to_FAQ: "read FAQ"
url_FAQ: "https://faq.demarches-simplifiees.fr/category/49-comment-tester-ma-demarche"
url_FAQ: "/faq#accordion-administrateur-2"
faq: Frequently Asked Questions

View file

@ -15,4 +15,5 @@ fr:
draft: "En test"
more_info_on_test: "Pour plus dinformation sur la phase de test"
go_to_FAQ: "consulter la FAQ"
url_FAQ: "https://faq.demarches-simplifiees.fr/category/49-comment-tester-ma-demarche"
url_FAQ: "/faq#accordion-administrateur-2"
faq: Foire aux Questions

View file

@ -715,6 +715,9 @@ Rails.application.routes.draw do
resources :release_notes, only: [:index]
resources :faq, only: [:index]
get '/faq/:category/:slug', to: 'faq#show', as: :faq
get '/404', to: 'errors#not_found'
get '/422', to: 'errors#unprocessable_entity'
get '/500', to: 'errors#internal_server_error'

View file

@ -0,0 +1,25 @@
---
category: "administrateur"
subcategory: "general"
slug: "ajouter-plusieurs-administrateurs-sur-une-meme-demarche"
locale: "fr"
keywords: "plusieurs administrateurs, droits dadministration, co-administrateur, gestion démarche"
title: "Ajouter plusieurs administrateurs sur une même démarche"
---
# Ajouter plusieurs administrateurs sur une même démarche
Il est possible davoir plusieurs administrateurs sur une même démarche. Cela permet à chaque administrateur de consulter les dossiers et dajuster le fonctionnement de la démarche, facilitant ainsi la gestion et le transfert des droits dadministration à une autre personne.
**Nous conseillons vivement à chaque administrateur de nommer un co-administrateur pour assurer une gestion continue de la démarche.**
![Capture décran de la page gérant la liste des administrateurs](faq/administrateur-add-administrateur.png)
## Comment ajouter un autre administrateur sur votre démarche ?
1. Si les personnes en question nont pas encore de compte administrateur, **faites une [demande de compte administrateur](%{application_base_url}/demandes/new)** et attendez que le compte soit approuvé.
2. Connectez-vous en tant quAdministrateur et **allez sur le tableau de bord de la démarche**.
3. Cliquez sur longlet **« Administrateurs »** de la démarche.
4. **Ajoutez ladresse email** du nouvel administrateur à la liste.
👏 La nouvelle personne pourra alors administrer la démarche !

View file

@ -0,0 +1,37 @@
---
category: "administrateur"
subcategory: "general"
slug: "comment-clore-une-demarche"
locale: "fr"
keywords: "clôture démarche, dé-publication, programmation clôture, tableau de bord"
title: "Comment clore une démarche ?"
---
# Comment clore une démarche ?
Pour rendre une démarche inaccessible au public, vous avez la possibilité de la clôturer à tout moment. Suite à la clôture, lURL de la démarche redirige lusager vers une page lui indiquant que la démarche recherchée est close accompagné dun message optionnel, et quil nest plus possible de commencer un nouveau dossier.
## Pour clore une démarche
Cliquez sur le bouton **« Clore »** situé à droite de la démarche.
Bien que laccès à la démarche soit restreint, les dossiers déjà déposés ne sont pas affectés et leur instruction peut se poursuivre normalement.
![Capture décran de la page de clôture de la demarche](faq/administrateur-procedure-action-close.png)
## Informer les usagers accédant à la démarche close
Un usager qui suit un lien vers la démarche sera informé quelle est close. Cependant au moment de la clôture vous pouvez indiquer quelle démarche la remplace (nous le redigerons vers celle-ci), ou la raison pour laquelle est close.
![Capture d'écran du remplacement de démarche](faq/administrateur-procedure-close-replace.png)
![Capture d'écran pour saisir le motif de cloture de démarche](faq/administrateur-procedure-close-message.png)
## Comment prévoir la clôture automatique dune démarche ?
Si vous anticipez la clôture de votre démarche à une date et/ou heure spécifique, il est possible de programmer cette clôture. Rendez-vous dans longlet **« Présentation »** de votre démarche, section **« Options avancées »**, pour définir les paramètres de clôture automatique.
![Capture décran de la configuration de fermeture à une date donnée](faq/administrateur-procedure-auto-archive.png)
Lorsquune démarche se clôture automatiquement, tous les dossiers en construction passent automatiquement au statut  en instruction »* à la date limite de dépôt des dossiers.

View file

@ -0,0 +1,32 @@
---
category: "administrateur"
subcategory: "general"
slug: "comment-comprendre-mon-tableau-de-bord-administrateur"
locale: "fr"
keywords: "tableau de bord, démarches publiées, démarches en test, démarches closes, démarches supprimées"
title: "Comment comprendre mon tableau de bord administrateur ?"
---
# Comment comprendre mon tableau de bord administrateur ?
Votre tableau de bord présente l'ensemble de vos démarches, classées en 4 catégories :
![Capture d'écran du tableau de bord administrateur](faq/administrateur-procedures-list-header.png)
## Publiées
Une démarche est considérée comme publiée lorsquelle est finalisée et active. Les usagers peuvent y déposer des dossiers.
## En test
Les démarches à létat de brouillon sont celles créées mais non finalisées et non publiées. Aucun usager ne peut y déposer des dossiers (à moins de disposer du lien de test de la démarche) et la démarche peut être modifiée à volonté.
**Attention : un dossier déposé sur une démarche en test sera définitivement supprimé**, et non récupérable, lorsque la démarche sera publiée. Ne publiez donc jamais le lien publiquement dune demarche en test. Gardez ce lien pour des tests internes.
## Closes
Une démarche close est une démarche qui a été active mais qui désormais ne permet plus le dépôt de nouveaux dossiers par les usagers. Les dossiers déposés peuvent toutefois toujours être instruits.
## Supprimées
Il s'agit des démarches supprimées par l'administrateur, quel que soit leur état (*« publiée »*,  en test »* ou  close »*). Ces démarches peuvent être restaurées en cliquant sur le bouton **« Actions »** puis **« Restaurer »**.

View file

@ -0,0 +1,16 @@
---
category: "administrateur"
subcategory: "create_procedure"
slug: "comment-creer-ma-demarche"
locale: "fr"
keywords: "création démarche, tutoriel, guide bonnes pratiques, administrateur"
title: "Comment créer ma démarche ?"
---
# Comment créer ma démarche ?
Envie de vous lancer dans laventure ? Bravo ! Pour vous accompagner tout au long de la création de votre démarche, nous avons préparé un petit tutoriel spécialement pour vous :
[Tutoriel Administrateur](https://doc.demarches-simplifiees.fr/tutoriels/tutoriel-administrateur)
Pour compléter cette prise en main de loutil, nhésitez pas à consulter [notre guide de bonnes pratiques](https://456404736-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-L7_aKvpAJdAIEfxHudA%2Fuploads%2FGJm7S7LVjHPKVlMCE36e%2FGuide%20des%20bonnes%20pratiques%20démarches-simplifiees.pdf?alt=media&token=228e63c7-a168-4656-9cda-3f53a10645c2).

View file

@ -0,0 +1,27 @@
---
category: "administrateur"
subcategory: "create_procedure"
slug: "comment-creer-une-demarche-declarative"
locale: "fr"
keywords: "démarche déclarative, co-construction, instruction automatique, configuration"
title: "Comment créer une démarche déclarative ?"
---
# Comment créer une démarche déclarative ?
## Quest-ce quune démarche déclarative ?
Une démarche déclarative est une démarche pour laquelle certaines étapes de linstruction sont simplifiées. Ce type de démarche diffère de linstruction classique par deux configurations possibles :
- **Sauter létape de construction** : les dossiers déposés passent automatiquement en instruction, et lusager ne peut plus modifier son dossier.
- **Sauter entièrement létape dinstruction** : les dossiers déposés sont tous automatiquement acceptés.
**Attention** : si vous optez pour une démarche déclarative, les usagers ne pourront pas modifier leur dossier après dépôt. Linstructeur devra repasser le dossier *« en construction »* pour permettre toute modification. Il est désormais possible de demander à lusager de modifier son dossier.
## Comment rendre une démarche déclarative ?
Pour configurer une démarche comme déclarative, accédez à la partie **« Présentation »** de la démarche depuis le tableau de bord administrateur. En bas de la page, dans longlet **« Options avancées »**, sélectionnez loption souhaitée (*« En instruction »* ou  Accepté »*) et enregistrez les modifications.
![Capture d'écran de la page de configuration de la demarche déclarative](faq/administrateur-create-declarative.png)
Vous avez la possibilité de revenir en arrière ou de modifier le type de démarche déclarative à tout moment, même après publication.

View file

@ -0,0 +1,27 @@
---
category: "administrateur"
subcategory: "create_procedure"
slug: "comment-limiter-une-demarche-dans-le-temps"
locale: "fr"
keywords: "clôture automatique, limite temporelle, appels à projet, fermer une démarche"
title: "Comment limiter une démarche dans le temps ?"
---
# Comment limiter une démarche dans le temps ?
La clôture automatique est une fonctionnalité qui permet de clore automatiquement le dépôt des dossiers à une date et heure prédéfinies, savérant particulièrement utile pour les appels à projet ou les démarches avec une période de candidature limitée.
## Fonctionnement de la clôture automatique
Lorsque la date limite est atteinte, la démarche devient inaccessible pour le dépôt de nouveaux dossiers par le public. Cependant, les usagers peuvent toujours consulter leurs dossiers déposés, et les instructeurs peuvent poursuivre linstruction des dossiers déjà reçus. Tous les dossiers déposés avant la date limite passent automatiquement en phase dinstruction, tandis que les dossiers encore en brouillon restent non soumis et ne peuvent plus être déposés.
## Activation de la clôture automatique
Pour mettre en place la clôture automatique :
1. Accédez à longlet « _Présentation_ » de votre démarche depuis le tableau de bord administrateur.
2. Dans les « _Options avancées_ », recherchez le champ intitulé « _Date limite de dépôt des dossiers_ » et renseignez la date souhaitée.
![Saisie de la date limite de dépôt](faq/administrateur-set-auto-close-date.png)
**Attention** : Si vous fixez la date de clôture au « 14 septembre », la fin de dépôt des dossiers sera effective le **14 septembre à 23h59 (heure de Paris)**.

View file

@ -0,0 +1,60 @@
---
category: "administrateur"
subcategory: "create_procedure"
slug: "comment-mettre-en-forme-le-texte-de-ma-demarche"
locale: "fr"
keywords: "mise en forme, HTML, balises, texte démarche, gras, italique, souligné"
title: "Comment mettre en forme le texte de ma démarche ?"
---
# Comment mettre en forme le texte de ma démarche ?
Il est possible de mettre en forme certaines parties de votre démarche en utilisant des balises HTML. Ces éléments de code vous permettent de :
- Mettre votre texte en *italique*
- <u>Souligner</u> votre texte
- Mettre votre texte en **gras**
- Faire un paragraphe
- Mettre votre texte sous forme de titre
## Quels sont les textes que je peux mettre en forme ?
Vous pouvez utiliser certaines balises HTML dans **les éléments de description générale** de votre démarche et dans **la description dun champ** de votre démarche. Les balises ne sont pas reconnues dans le libellé de votre démarche et ne peuvent donc pas être mises en forme.
## Comment mettre en forme mon texte ?
Pour cela, utilisez les balises HTML, identifiées par les caractères `<` et `>`, avec une balise ouvrante (ex : `<p>`) et une balise fermante (ex : `</p>`). Notez que la balise fermante inclut une barre oblique `/` (slash) après le `<`.
### Exemples de mise en forme :
- **Mettre un texte en italique**
- Balise ouvrante : `<em>`
- Balise fermante : `</em>`
- Exemple : « `Mon texte en <em>italique</em>` » affiche « Mon texte en *italique* »
- **Souligner un texte**
- Balise ouvrante : `<u>`
- Balise fermante : `</u>`
- Exemple :  Mon texte <u>souligné</u> »` affiche « Mon texte <u>souligné</u> »
- **Mettre un texte en gras**
- Balise ouvrante : `<strong>`
- Balise fermante : `</strong>`
- Exemple :  Mon texte en <strong>gras</strong> »` donne « Mon texte en **gras** »
- **Faire un paragraphe**
- Balise ouvrante : `<p>`
- Balise fermante : `</p>`
- Exemple : `<p>Mon paragraphe</p>`.
Généralement vous naurez pas besoin de créer un paragraphe, car un saut de ligne vide en créé toujours un nouveau.
## Aperçu du texte avec ces balises
Exemple dans la description de la démarche :
![Démonstration de texte qui contient des balises HTML de mises en forme](faq/administrateur-example-markup.png)
Rendu côté usager :
![Aperçu du même texte dans la description de la démarche lisible par lusager](faq/administrateur-example-markup-preview.png)

View file

@ -0,0 +1,31 @@
---
category: "administrateur"
subcategory: "general"
slug: "comment-modifier-une-demarche-deja-publiee"
locale: "fr"
keywords: "modifier démarche, publication, mise à jour formulaire, brouillon"
title: "Comment modifier une démarche déjà publiée ?"
---
# Comment modifier une démarche déjà publiée ?
La plupart des caractéristiques de la démarche peuvent être modifiées après la publication, comme :
- le nom et la description
- le formulaire en lui-même
- la délivrance et le contenu de lattestation
- la plupart des réglages, à lexception du chemin (lurl) et les réglages liées au *Silence Vaut Accord* ou *Silence Vaut Rejet*
## Modification du formulaire
Vous disposez des mêmes options que lors de la création dun formulaire. Pour valider les changements sur votre formulaire, cliquez simplement sur le bouton **« Publier »**.
Les modifications apportées au formulaire sappliqueront uniquement sur :
- les dossiers en  brouillon »* et les futurs dossiers (cest-à-dire ceux déposés après la publication de vos modifications)
- les dossiers en  en construction »* et  en instruction »* compatibles (par exemple : si vous supprimez un champ ou modifiez les annotations privées)
- les autres dossiers en  en construction »* au moment où lusager modifier son dossier
**Les dossiers *terminés* ne sont pas modifiés.**

Some files were not shown because too many files have changed in this diff Show more