Refactor and redesign publish modal
* remove the autocomplete menu * use ujs to pre-validate the procedure * tweak the UI
This commit is contained in:
parent
bd1e0aba38
commit
c26a701a17
18 changed files with 148 additions and 292 deletions
|
@ -1,70 +0,0 @@
|
||||||
/* globals $ */
|
|
||||||
|
|
||||||
$(document).on('turbolinks:load', init_path_modal);
|
|
||||||
|
|
||||||
var PROCEDURE_PATH_SELECTOR = 'input[data-autocomplete=path]';
|
|
||||||
|
|
||||||
function init_path_modal() {
|
|
||||||
path_modal_action();
|
|
||||||
path_validation_action();
|
|
||||||
path_type_init();
|
|
||||||
path_validation($(PROCEDURE_PATH_SELECTOR));
|
|
||||||
}
|
|
||||||
|
|
||||||
function path_modal_action() {
|
|
||||||
$('#publish-modal').on('show.bs.modal', function(event) {
|
|
||||||
$('#publish-modal .modal-body .table .tr-content').hide();
|
|
||||||
|
|
||||||
var button = $(event.relatedTarget); // Button that triggered the modal
|
|
||||||
var modal_title = button.data('modal_title'); // Extract info from data-* attributes
|
|
||||||
var modal_index = button.data('modal_index'); // Extract info from data-* attributes
|
|
||||||
|
|
||||||
var modal = $(this);
|
|
||||||
modal.find('#publish-modal-title').html(modal_title);
|
|
||||||
$('#publish-modal .modal-body .table #' + modal_index).show();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function path_validation_action() {
|
|
||||||
$(PROCEDURE_PATH_SELECTOR).keyup(function(key) {
|
|
||||||
if (key.keyCode != 13) path_validation(this);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function togglePathMessage(valid, mine) {
|
|
||||||
$('#path-messages .message').hide();
|
|
||||||
|
|
||||||
if (valid === true && mine === true) {
|
|
||||||
$('#path_is_mine').show();
|
|
||||||
} else if (valid === true && mine === false) {
|
|
||||||
$('#path_is_not_mine').show();
|
|
||||||
} else if (valid === false && mine === null) {
|
|
||||||
$('#path_is_invalid').show();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((valid && mine === null) || mine === true)
|
|
||||||
$('#publish-modal #publish').removeAttr('disabled');
|
|
||||||
else $('#publish-modal #publish').attr('disabled', 'disabled');
|
|
||||||
}
|
|
||||||
|
|
||||||
function path_validation(el) {
|
|
||||||
var valid = validatePath($(el).val());
|
|
||||||
toggleErrorClass(el, valid);
|
|
||||||
togglePathMessage(valid, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleErrorClass(node, boolean) {
|
|
||||||
if (boolean) $(node).removeClass('input-error');
|
|
||||||
else $(node).addClass('input-error');
|
|
||||||
}
|
|
||||||
|
|
||||||
function validatePath(path) {
|
|
||||||
var re = /^[a-z0-9_-]{3,50}$/;
|
|
||||||
return re.test(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
function path_type_init() {
|
|
||||||
$(PROCEDURE_PATH_SELECTOR).on('autocomplete:select', function(event) {
|
|
||||||
togglePathMessage(true, event.detail['mine']);
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -1,24 +0,0 @@
|
||||||
.path-mine-false {
|
|
||||||
color: #FF0000;
|
|
||||||
}
|
|
||||||
|
|
||||||
#path-messages {
|
|
||||||
.message {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#publish-modal {
|
|
||||||
.algolia-autocomplete {
|
|
||||||
width: 300px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.aa-dropdown-menu {
|
|
||||||
width: 300px;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fix the input not being displayed on the same line than the text before
|
|
||||||
.aa-input {
|
|
||||||
vertical-align: initial !important;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -13,7 +13,6 @@
|
||||||
// = require _card
|
// = require _card
|
||||||
// = require _helpers
|
// = require _helpers
|
||||||
// = require _turbolinks
|
// = require _turbolinks
|
||||||
// = require admin_procedures_modal
|
|
||||||
// = require admin_type_de_champ
|
// = require admin_type_de_champ
|
||||||
// = require carte
|
// = require carte
|
||||||
// = require custom_mails
|
// = require custom_mails
|
||||||
|
|
|
@ -2,7 +2,7 @@ class Admin::ProceduresController < AdminController
|
||||||
include SmartListing::Helper::ControllerExtensions
|
include SmartListing::Helper::ControllerExtensions
|
||||||
helper SmartListing::Helper
|
helper SmartListing::Helper
|
||||||
|
|
||||||
before_action :retrieve_procedure, only: [:show, :edit, :delete_logo, :delete_deliberation, :delete_notice, :monavis, :update_monavis]
|
before_action :retrieve_procedure, only: [:show, :edit, :delete_logo, :delete_deliberation, :delete_notice, :monavis, :update_monavis, :publish_validate, :publish]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
if current_administrateur.procedures.count != 0
|
if current_administrateur.procedures.count != 0
|
||||||
|
@ -40,7 +40,8 @@ class Admin::ProceduresController < AdminController
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@suggested_path = @procedure.suggested_path(current_administrateur)
|
@procedure.path = @procedure.suggested_path(current_administrateur)
|
||||||
|
@current_administrateur = current_administrateur
|
||||||
end
|
end
|
||||||
|
|
||||||
def edit
|
def edit
|
||||||
|
@ -94,33 +95,19 @@ class Admin::ProceduresController < AdminController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def publish
|
def publish_validate
|
||||||
path = params[:path]
|
@procedure.assign_attributes(publish_params)
|
||||||
lien_site_web = params[:lien_site_web]
|
end
|
||||||
procedure = current_administrateur.procedures.find(params[:procedure_id])
|
|
||||||
|
def publish
|
||||||
|
@procedure.assign_attributes(publish_params)
|
||||||
|
|
||||||
|
@procedure.publish_or_reopen!(current_administrateur)
|
||||||
|
|
||||||
procedure.publish_or_reopen!(current_administrateur, path, lien_site_web)
|
|
||||||
flash.notice = "Démarche publiée"
|
flash.notice = "Démarche publiée"
|
||||||
redirect_to admin_procedures_path
|
redirect_to admin_procedures_path
|
||||||
rescue ActiveRecord::RecordInvalid => e
|
rescue ActiveRecord::RecordInvalid
|
||||||
errors = e.record.errors
|
render 'publish_validate', formats: :js
|
||||||
if errors.details.key?(:path)
|
|
||||||
path_error = errors.details.dig(:path, 0, :error)
|
|
||||||
case path_error
|
|
||||||
when :invalid
|
|
||||||
@valid = false
|
|
||||||
when :taken
|
|
||||||
@valid = true
|
|
||||||
@mine = false
|
|
||||||
end
|
|
||||||
render '/admin/procedures/publish', formats: 'js'
|
|
||||||
else
|
|
||||||
flash.alert = errors.full_messages
|
|
||||||
return redirect_to admin_procedure_path(procedure)
|
|
||||||
end
|
|
||||||
rescue ActiveRecord::RecordNotFound
|
|
||||||
flash.alert = 'Démarche inexistante'
|
|
||||||
redirect_to admin_procedures_path
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def transfer
|
def transfer
|
||||||
|
@ -214,20 +201,6 @@ class Admin::ProceduresController < AdminController
|
||||||
@draft_class = 'active'
|
@draft_class = 'active'
|
||||||
end
|
end
|
||||||
|
|
||||||
def path_list
|
|
||||||
json_path_list = Procedure
|
|
||||||
.find_with_path(params[:request])
|
|
||||||
.order(:id)
|
|
||||||
.map do |procedure|
|
|
||||||
{
|
|
||||||
label: procedure.path,
|
|
||||||
mine: current_administrateur.owns?(procedure)
|
|
||||||
}
|
|
||||||
end.to_json
|
|
||||||
|
|
||||||
render json: json_path_list
|
|
||||||
end
|
|
||||||
|
|
||||||
def delete_logo
|
def delete_logo
|
||||||
@procedure.logo.purge_later
|
@procedure.logo.purge_later
|
||||||
@procedure.logo_active_storage.purge_later
|
@procedure.logo_active_storage.purge_later
|
||||||
|
@ -256,6 +229,10 @@ class Admin::ProceduresController < AdminController
|
||||||
params[:from_new_from_existing].present?
|
params[:from_new_from_existing].present?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def publish_params
|
||||||
|
params.permit(:path, :lien_site_web)
|
||||||
|
end
|
||||||
|
|
||||||
def procedure_params
|
def procedure_params
|
||||||
editable_params = [:libelle, :description, :organisation, :direction, :lien_site_web, :cadre_juridique, :deliberation, :notice, :web_hook_url, :euro_flag, :logo, :auto_archive_on, :monavis_embed]
|
editable_params = [:libelle, :description, :organisation, :direction, :lien_site_web, :cadre_juridique, :deliberation, :notice, :web_hook_url, :euro_flag, :logo, :auto_archive_on, :monavis_embed]
|
||||||
permited_params = if @procedure&.locked?
|
permited_params = if @procedure&.locked?
|
||||||
|
|
|
@ -5,10 +5,6 @@ const sources = [
|
||||||
{
|
{
|
||||||
type: 'address',
|
type: 'address',
|
||||||
url: '/address/suggestions'
|
url: '/address/suggestions'
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'path',
|
|
||||||
url: '/admin/procedures/path_list'
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,7 @@ class Procedure < ApplicationRecord
|
||||||
validates :description, presence: true, allow_blank: false, allow_nil: false
|
validates :description, presence: true, allow_blank: false, allow_nil: false
|
||||||
validates :administrateurs, presence: true
|
validates :administrateurs, presence: true
|
||||||
validates :lien_site_web, presence: true, if: :publiee?
|
validates :lien_site_web, presence: true, if: :publiee?
|
||||||
|
validate :validate_for_publication, on: :publication
|
||||||
validate :check_juridique
|
validate :check_juridique
|
||||||
validates :path, presence: true, format: { with: /\A[a-z0-9_\-]{3,50}\z/ }, uniqueness: { scope: [:path, :archived_at, :hidden_at], case_sensitive: false }
|
validates :path, presence: true, format: { with: /\A[a-z0-9_\-]{3,50}\z/ }, uniqueness: { scope: [:path, :archived_at, :hidden_at], case_sensitive: false }
|
||||||
# FIXME: remove duree_conservation_required flag once all procedures are converted to the new style
|
# FIXME: remove duree_conservation_required flag once all procedures are converted to the new style
|
||||||
|
@ -107,12 +108,18 @@ class Procedure < ApplicationRecord
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def publish_or_reopen!(administrateur, path, lien_site_web)
|
def publish_or_reopen!(administrateur)
|
||||||
Procedure.transaction do
|
Procedure.transaction do
|
||||||
if brouillon?
|
if brouillon?
|
||||||
reset!
|
reset!
|
||||||
end
|
end
|
||||||
publish!(administrateur, path, lien_site_web)
|
|
||||||
|
other_procedure = other_procedure_with_path(path)
|
||||||
|
if other_procedure.present? && administrateur.owns?(other_procedure)
|
||||||
|
other_procedure.archive!
|
||||||
|
end
|
||||||
|
|
||||||
|
publish!
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -124,6 +131,44 @@ class Procedure < ApplicationRecord
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def validate_for_publication
|
||||||
|
old_attributes = self.slice(:aasm_state, :archived_at)
|
||||||
|
self.aasm_state = :publiee
|
||||||
|
self.archived_at = nil
|
||||||
|
|
||||||
|
is_valid = validate
|
||||||
|
|
||||||
|
self.attributes = old_attributes
|
||||||
|
|
||||||
|
is_valid
|
||||||
|
end
|
||||||
|
|
||||||
|
def suggested_path(administrateur)
|
||||||
|
if path_customized?
|
||||||
|
return path
|
||||||
|
end
|
||||||
|
slug = libelle&.parameterize&.first(50)
|
||||||
|
suggestion = slug
|
||||||
|
counter = 1
|
||||||
|
while !path_available?(administrateur, suggestion)
|
||||||
|
counter = counter + 1
|
||||||
|
suggestion = "#{slug}-#{counter}"
|
||||||
|
end
|
||||||
|
suggestion
|
||||||
|
end
|
||||||
|
|
||||||
|
def other_procedure_with_path(path)
|
||||||
|
Procedure.publiees
|
||||||
|
.where.not(id: self.id)
|
||||||
|
.find_by(path: path)
|
||||||
|
end
|
||||||
|
|
||||||
|
def path_available?(administrateur, path)
|
||||||
|
procedure = other_procedure_with_path(path)
|
||||||
|
|
||||||
|
procedure.blank? || administrateur.owns?(procedure)
|
||||||
|
end
|
||||||
|
|
||||||
def locked?
|
def locked?
|
||||||
publiee_ou_archivee?
|
publiee_ou_archivee?
|
||||||
end
|
end
|
||||||
|
@ -171,20 +216,6 @@ class Procedure < ApplicationRecord
|
||||||
!path.match?(/[[:xdigit:]]{8}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{12}/)
|
!path.match?(/[[:xdigit:]]{8}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{12}/)
|
||||||
end
|
end
|
||||||
|
|
||||||
def suggested_path(administrateur)
|
|
||||||
if path_customized?
|
|
||||||
return path
|
|
||||||
end
|
|
||||||
slug = libelle&.parameterize&.first(50)
|
|
||||||
suggestion = slug
|
|
||||||
counter = 1
|
|
||||||
while !path_available?(administrateur, suggestion)
|
|
||||||
counter = counter + 1
|
|
||||||
suggestion = "#{slug}-#{counter}"
|
|
||||||
end
|
|
||||||
suggestion
|
|
||||||
end
|
|
||||||
|
|
||||||
def organisation_name
|
def organisation_name
|
||||||
service&.nom || organisation
|
service&.nom || organisation
|
||||||
end
|
end
|
||||||
|
@ -377,26 +408,6 @@ class Procedure < ApplicationRecord
|
||||||
percentile_time(:en_construction_at, :processed_at, 90)
|
percentile_time(:en_construction_at, :processed_at, 90)
|
||||||
end
|
end
|
||||||
|
|
||||||
def path_available?(administrateur, path)
|
|
||||||
procedure = Procedure.publiees
|
|
||||||
.where.not(id: self.id)
|
|
||||||
.find_by(path: path)
|
|
||||||
|
|
||||||
procedure.blank? || administrateur.owns?(procedure)
|
|
||||||
end
|
|
||||||
|
|
||||||
def auto_archive_procedure_with_same_path(administrateur, path)
|
|
||||||
procedure = administrateur.procedures.publiees
|
|
||||||
.where.not(id: self.id)
|
|
||||||
.find_by(path: path)
|
|
||||||
|
|
||||||
procedure&.archive!
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.find_with_path(path)
|
|
||||||
where.not(aasm_state: :archivee).where("path LIKE ?", "%#{path}%")
|
|
||||||
end
|
|
||||||
|
|
||||||
def populate_champ_stable_ids
|
def populate_champ_stable_ids
|
||||||
TypeDeChamp.where(procedure: self, stable_id: nil).find_each do |type_de_champ|
|
TypeDeChamp.where(procedure: self, stable_id: nil).find_each do |type_de_champ|
|
||||||
type_de_champ.update_column(:stable_id, type_de_champ.id)
|
type_de_champ.update_column(:stable_id, type_de_champ.id)
|
||||||
|
@ -490,12 +501,11 @@ class Procedure < ApplicationRecord
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def before_publish(administrateur, path, lien_site_web)
|
def before_publish
|
||||||
auto_archive_procedure_with_same_path(administrateur, path)
|
update!(archived_at: nil)
|
||||||
update!(path: path, lien_site_web: lien_site_web, archived_at: nil)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def after_publish(administrateur, path, lien_site_web)
|
def after_publish
|
||||||
update!(published_at: Time.zone.now)
|
update!(published_at: Time.zone.now)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,63 +1,49 @@
|
||||||
#publish-modal.modal{ "aria-labelledby" => "myModalLabel", :role => "dialog", :tabindex => "-1" }
|
#publish-modal.modal{ "aria-labelledby" => "myModalLabel", :role => "dialog", :tabindex => "-1" }
|
||||||
.modal-dialog.modal-lg{ :role => "document" }
|
.modal-dialog.modal-lg{ :role => "document" }
|
||||||
= form_tag admin_procedure_publish_path(procedure_id: @procedure.id), method: :put, remote: true do
|
= form_tag admin_procedure_publish_path(procedure_id: procedure.id), method: :put, remote: true do
|
||||||
.modal-content
|
.modal-content
|
||||||
.modal-header
|
.modal-header
|
||||||
%button.close{ "aria-label" => "Close", "data-dismiss" => "modal", :type => "button" }
|
%button.close{ "aria-label" => "Close", "data-dismiss" => "modal", :type => "button" }
|
||||||
%span{ "aria-hidden" => "true" } ×
|
%span{ "aria-hidden" => "true" } ×
|
||||||
%h4#myModalLabel.modal-title
|
%h4#myModalLabel.modal-title
|
||||||
= procedure_modal_text(@procedure, :title)
|
= procedure_modal_text(procedure, :title)
|
||||||
%span#publish-modal-title
|
%span#publish-modal-title
|
||||||
.modal-body
|
.modal-body
|
||||||
= procedure_modal_text(@procedure, :body)
|
.text-info
|
||||||
- if !@procedure.archivee?
|
%p
|
||||||
%b
|
= procedure_modal_text(procedure, :body)
|
||||||
Elle ne pourra plus être modifiée à l’issue de cette publication.
|
%b Elle ne pourra plus être modifiée à l’issue de cette publication.
|
||||||
%br
|
|
||||||
Afin de faciliter l’accès à la démarche, vous êtes invité à personnaliser l’adresse d'accès si vous le souhaitez.
|
|
||||||
%br
|
|
||||||
.form-group
|
.form-group
|
||||||
%br
|
%h4 Adresse de la démarche
|
||||||
%h4 Lien de la démarche
|
%p Vous pouvez personnaliser le lien public de la démarche pour en faciliter l’accès.
|
||||||
%p.center
|
%p
|
||||||
= commencer_url(path: '')
|
= commencer_url(path: '')
|
||||||
= text_field_tag(:path, @suggested_path,
|
= text_field_tag(:path, procedure.path,
|
||||||
id: 'procedure_path',
|
id: 'procedure_path',
|
||||||
placeholder: 'Chemin vers la démarche',
|
placeholder: 'chemin-de-la-démarche',
|
||||||
data: { autocomplete: 'path' },
|
required: true,
|
||||||
class: 'form-control',
|
class: 'form-control',
|
||||||
maxlength: 50,
|
pattern: '^[a-z0-9_-]{3,50}$',
|
||||||
style: 'width: 300px; display: inline;')
|
title: "De 3 à 50 caractères; minuscules, chiffres et tiret seulement",
|
||||||
%br
|
data: { remote: true, debounce: true, url: admin_procedure_publish_validate_path(procedure) },
|
||||||
.alert.alert-info
|
autocomplete: 'off',
|
||||||
Attention, diffusez toujours le <strong>lien complet</strong> affiché ci-dessus, et non pas un lien générique vers demarches-simplifiees.fr. Ne dites pas non plus aux usagers de se rendre sur le site générique demarches-simplifiees.fr, donnez-leur toujours le lien complet.
|
style: 'width: 300px; display: inline;')
|
||||||
%br
|
= render 'publish_path_message', procedure: procedure, administrateur: administrateur
|
||||||
%br
|
.text-info
|
||||||
Prenez quelques minutes pour savoir comment établir une bonne relation avec les usagers de votre démarche :
|
Attention, diffusez toujours le <strong>lien complet</strong> affiché ci-dessus, et non pas un lien générique vers demarches-simplifiees.fr. Ne dites pas non plus aux usagers de se rendre sur le site générique demarches-simplifiees.fr, donnez-leur toujours le lien complet.
|
||||||
= link_to "Regarder la vidéo de 5 minutes",
|
|
||||||
"https://vimeo.com/334463514",
|
|
||||||
target: "_blank"
|
|
||||||
|
|
||||||
.form-group
|
.form-group
|
||||||
%h4 Où les usagers trouveront-ils le lien vers cette démarche ? *
|
%h4 Diffusion de la démarche
|
||||||
|
%p Où les utilisateurs trouveront-ils le lien de la démarche ? Typiquement, il s’agit d’une page de votre site web.
|
||||||
%p.center
|
%p.center
|
||||||
= text_field_tag(:lien_site_web, @procedure.lien_site_web,
|
= text_field_tag(:lien_site_web, procedure.lien_site_web,
|
||||||
required: true,
|
required: true,
|
||||||
class: 'form-control',
|
class: 'form-control',
|
||||||
|
autocomplete: 'off',
|
||||||
placeholder: 'https://exemple.gouv.fr/ma_demarche')
|
placeholder: 'https://exemple.gouv.fr/ma_demarche')
|
||||||
|
.text-info
|
||||||
#path-messages
|
Prenez quelques minutes pour savoir comment établir une bonne relation avec les usagers de votre démarche :
|
||||||
#path_is_mine.text-warning.center.message
|
= link_to "Regarder la vidéo de 5 minutes.",
|
||||||
Ce lien est déjà utilisé par une de vos démarche.
|
"https://vimeo.com/334463514",
|
||||||
%br
|
target: "_blank"
|
||||||
Si vous voulez l’utiliser, l’ancienne démarche sera archivée (plus accessible du public).
|
|
||||||
#path_is_not_mine.text-danger.center.message
|
|
||||||
Ce lien est déjà utilisé par une démarche.
|
|
||||||
%br
|
|
||||||
Vous ne pouvez pas l’utiliser car il appartient à un autre administrateur.
|
|
||||||
#path_is_invalid.text-danger.center.message
|
|
||||||
Ce lien
|
|
||||||
= t('activerecord.errors.models.procedure.attributes.path.invalid')
|
|
||||||
.modal-footer
|
.modal-footer
|
||||||
= submit_tag procedure_modal_text(@procedure, :submit), class: %w(btn btn btn-success), disabled: :disabled, id: 'publish'
|
= render 'publish_buttons', procedure: procedure, administrateur: administrateur
|
||||||
= button_tag "Annuler", class: %w(btn btn btn-default), data: { dismiss: :modal }, id: 'cancel'
|
|
||||||
|
|
13
app/views/admin/procedures/_publish_buttons.html.haml
Normal file
13
app/views/admin/procedures/_publish_buttons.html.haml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#publish-buttons
|
||||||
|
= button_tag "Annuler", class: %w(btn btn-default), data: { dismiss: :modal }
|
||||||
|
|
||||||
|
- procedure.validate(:publication)
|
||||||
|
- errors = procedure.errors
|
||||||
|
-# Ignore the :taken error if the path can be claimed
|
||||||
|
- if errors.details[:path]&.pluck(:error)&.include?(:taken) && procedure.path_available?(administrateur, procedure.path)
|
||||||
|
- errors.delete(:path)
|
||||||
|
|
||||||
|
- options = { class: %w(btn btn-success), id: 'publish' }
|
||||||
|
- if errors.details[:path].present?
|
||||||
|
- options[:disabled] = :disabled
|
||||||
|
= submit_tag procedure_modal_text(@procedure, :submit), options
|
11
app/views/admin/procedures/_publish_path_message.html.haml
Normal file
11
app/views/admin/procedures/_publish_path_message.html.haml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#publish-path-message
|
||||||
|
- procedure.validate(:publication)
|
||||||
|
- errors = procedure.errors
|
||||||
|
-# Ignore the :taken error if the path can be claimed, and instead display the :taken_can_be_claimed error message.
|
||||||
|
- if errors.details[:path]&.pluck(:error)&.include?(:taken) && procedure.path_available?(administrateur, procedure.path)
|
||||||
|
.alert.alert-warning
|
||||||
|
= errors.full_message('Le lien public', errors.generate_message(:path, :taken_can_be_claimed))
|
||||||
|
- elsif errors.messages[:path].present?
|
||||||
|
-# Display the actual errors for :path
|
||||||
|
.alert.alert-danger
|
||||||
|
= errors.full_message('Le lien public', errors.messages[:path].first)
|
|
@ -1 +0,0 @@
|
||||||
<%= "togglePathMessage(#{@valid}, #{@mine})" %>
|
|
4
app/views/admin/procedures/publish_validate.js.haml
Normal file
4
app/views/admin/procedures/publish_validate.js.haml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
= render_to_element("#publish-path-message", partial: 'publish_path_message', outer: true,
|
||||||
|
locals: { procedure: @procedure, administrateur: current_administrateur })
|
||||||
|
= render_to_element("#publish-buttons", partial: 'publish_buttons', outer: true,
|
||||||
|
locals: { procedure: @procedure, administrateur: current_administrateur })
|
|
@ -1,7 +1,7 @@
|
||||||
= render partial: 'admin/closed_mail_template_attestation_inconsistency_alert'
|
= render partial: 'admin/closed_mail_template_attestation_inconsistency_alert'
|
||||||
.row.white-back
|
.row.white-back
|
||||||
#procedure_show
|
#procedure_show
|
||||||
= render partial: '/admin/procedures/modal_publish'
|
= render 'modal_publish', procedure: @procedure, administrateur: @current_administrateur
|
||||||
= render partial: '/admin/procedures/modal_transfer'
|
= render partial: '/admin/procedures/modal_transfer'
|
||||||
|
|
||||||
- if @procedure.brouillon?
|
- if @procedure.brouillon?
|
||||||
|
@ -117,7 +117,7 @@
|
||||||
- if @procedure.missing_steps.include?(:service)
|
- if @procedure.missing_steps.include?(:service)
|
||||||
%p.alert.alert-danger
|
%p.alert.alert-danger
|
||||||
Vous devez renseigner les coordonnées de votre Service administratif avant de pouvoir publier votre démarche.
|
Vous devez renseigner les coordonnées de votre Service administratif avant de pouvoir publier votre démarche.
|
||||||
= link_to 'Cliquez ici.', (current_administrateur.services.present? ? url_for(services_path(procedure_id: @procedure.id)) : url_for(new_service_path(procedure_id: @procedure.id)))
|
= link_to 'Cliquez ici.', (@current_administrateur.services.present? ? url_for(services_path(procedure_id: @procedure.id)) : url_for(new_service_path(procedure_id: @procedure.id)))
|
||||||
|
|
||||||
- if @procedure.missing_steps.include?(:instructeurs)
|
- if @procedure.missing_steps.include?(:instructeurs)
|
||||||
%p.alert.alert-danger
|
%p.alert.alert-danger
|
||||||
|
|
|
@ -163,6 +163,8 @@ fr:
|
||||||
procedure:
|
procedure:
|
||||||
attributes:
|
attributes:
|
||||||
path:
|
path:
|
||||||
|
taken: est déjà utilisé par une démarche. Vous ne pouvez pas l’utiliser car il appartient à un autre administrateur.
|
||||||
|
taken_can_be_claimed: est identique à celui d’une autre de vos démarches publiées. Si vous publiez cette démarche, l’ancienne sera archivée et ne sera plus accessible au public.
|
||||||
invalid: n'est pas valide. Il doit comporter au moins 3 caractères, au plus 50 caractères et seuls les caractères a-z, 0-9, '_' et '-' sont autorisés.
|
invalid: n'est pas valide. Il doit comporter au moins 3 caractères, au plus 50 caractères et seuls les caractères a-z, 0-9, '_' et '-' sont autorisés.
|
||||||
|
|
||||||
errors:
|
errors:
|
||||||
|
|
|
@ -159,7 +159,6 @@ Rails.application.routes.draw do
|
||||||
patch 'activate' => '/administrateurs/activate#create'
|
patch 'activate' => '/administrateurs/activate#create'
|
||||||
get 'procedures/archived' => 'procedures#archived'
|
get 'procedures/archived' => 'procedures#archived'
|
||||||
get 'procedures/draft' => 'procedures#draft'
|
get 'procedures/draft' => 'procedures#draft'
|
||||||
get 'procedures/path_list' => 'procedures#path_list'
|
|
||||||
|
|
||||||
resources :procedures do
|
resources :procedures do
|
||||||
collection do
|
collection do
|
||||||
|
@ -175,6 +174,7 @@ Rails.application.routes.draw do
|
||||||
resources :mail_templates, only: [:index, :edit, :update]
|
resources :mail_templates, only: [:index, :edit, :update]
|
||||||
|
|
||||||
put 'archive' => 'procedures#archive', as: :archive
|
put 'archive' => 'procedures#archive', as: :archive
|
||||||
|
get 'publish_validate' => 'procedures#publish_validate', as: :publish_validate
|
||||||
put 'publish' => 'procedures#publish', as: :publish
|
put 'publish' => 'procedures#publish', as: :publish
|
||||||
post 'transfer' => 'procedures#transfer', as: :transfer
|
post 'transfer' => 'procedures#transfer', as: :transfer
|
||||||
put 'clone' => 'procedures#clone', as: :clone
|
put 'clone' => 'procedures#clone', as: :clone
|
||||||
|
|
|
@ -340,7 +340,7 @@ describe Admin::ProceduresController, type: :controller do
|
||||||
|
|
||||||
context 'when admin is the owner of the procedure' do
|
context 'when admin is the owner of the procedure' do
|
||||||
before do
|
before do
|
||||||
put :publish, params: { procedure_id: procedure.id, path: path, lien_site_web: lien_site_web }
|
put :publish, format: :js, params: { procedure_id: procedure.id, path: path, lien_site_web: lien_site_web }
|
||||||
procedure.reload
|
procedure.reload
|
||||||
procedure2.reload
|
procedure2.reload
|
||||||
end
|
end
|
||||||
|
@ -383,8 +383,6 @@ describe Admin::ProceduresController, type: :controller do
|
||||||
expect(procedure.publiee?).to be_falsey
|
expect(procedure.publiee?).to be_falsey
|
||||||
expect(procedure.path).not_to match(path)
|
expect(procedure.path).not_to match(path)
|
||||||
expect(procedure.lien_site_web).to match(lien_site_web)
|
expect(procedure.lien_site_web).to match(lien_site_web)
|
||||||
expect(assigns(:valid)).to eq true
|
|
||||||
expect(assigns(:mine)).to eq false
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'previous procedure remains published' do
|
it 'previous procedure remains published' do
|
||||||
|
@ -402,7 +400,6 @@ describe Admin::ProceduresController, type: :controller do
|
||||||
expect(procedure.publiee?).to be_falsey
|
expect(procedure.publiee?).to be_falsey
|
||||||
expect(procedure.path).not_to match(path)
|
expect(procedure.path).not_to match(path)
|
||||||
expect(procedure.lien_site_web).to match(lien_site_web)
|
expect(procedure.lien_site_web).to match(lien_site_web)
|
||||||
expect(assigns(:valid)).to eq false
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -419,8 +416,7 @@ describe Admin::ProceduresController, type: :controller do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'fails' do
|
it 'fails' do
|
||||||
expect(response).to redirect_to :admin_procedures
|
expect(response).to have_http_status(404)
|
||||||
expect(flash[:alert]).to have_content 'Démarche inexistante'
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -573,54 +569,6 @@ describe Admin::ProceduresController, type: :controller do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'GET #path_list' do
|
|
||||||
let!(:procedure) { create(:procedure, :published, administrateur: admin) }
|
|
||||||
let(:admin2) { create(:administrateur) }
|
|
||||||
let!(:procedure2) { create(:procedure, :published, administrateur: admin2) }
|
|
||||||
let!(:procedure3) { create(:procedure, :published, administrateur: admin2) }
|
|
||||||
|
|
||||||
subject { get :path_list }
|
|
||||||
|
|
||||||
let(:body) { JSON.parse(response.body) }
|
|
||||||
|
|
||||||
describe 'when no params' do
|
|
||||||
before do
|
|
||||||
subject
|
|
||||||
end
|
|
||||||
|
|
||||||
it { expect(response.status).to eq(200) }
|
|
||||||
it { expect(body.size).to eq(3) }
|
|
||||||
it { expect(body.first['label']).to eq(procedure.path) }
|
|
||||||
it { expect(body.first['mine']).to be_truthy }
|
|
||||||
it { expect(body.second['label']).to eq(procedure2.path) }
|
|
||||||
it { expect(body.second['mine']).to be_falsy }
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'filtered' do
|
|
||||||
before do
|
|
||||||
subject
|
|
||||||
end
|
|
||||||
|
|
||||||
subject { get :path_list, params: { request: URI.encode(procedure2.path) } }
|
|
||||||
|
|
||||||
it { expect(response.status).to eq(200) }
|
|
||||||
it { expect(body.size).to eq(1) }
|
|
||||||
it { expect(body.first['label']).to eq(procedure2.path) }
|
|
||||||
it { expect(body.first['mine']).to be_falsy }
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when procedure is archived' do
|
|
||||||
let!(:procedure3) { create(:procedure, :archived, administrateur: admin2) }
|
|
||||||
before do
|
|
||||||
subject
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'do not return on the json' do
|
|
||||||
expect(body.size).to eq(2)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe 'POST #transfer' do
|
describe 'POST #transfer' do
|
||||||
let!(:procedure) { create :procedure, :with_service, administrateur: admin }
|
let!(:procedure) { create :procedure, :with_service, administrateur: admin }
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,8 @@ FactoryBot.define do
|
||||||
after(:build) do |procedure, _evaluator|
|
after(:build) do |procedure, _evaluator|
|
||||||
procedure.for_individual = true
|
procedure.for_individual = true
|
||||||
procedure.types_de_champ << create(:type_de_champ, libelle: 'Texte obligatoire', mandatory: true)
|
procedure.types_de_champ << create(:type_de_champ, libelle: 'Texte obligatoire', mandatory: true)
|
||||||
procedure.publish!(procedure.administrateurs.first, generate(:published_path), procedure.lien_site_web)
|
procedure.path = generate(:published_path)
|
||||||
|
procedure.publish!
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -148,13 +149,15 @@ FactoryBot.define do
|
||||||
|
|
||||||
trait :published do
|
trait :published do
|
||||||
after(:build) do |procedure, _evaluator|
|
after(:build) do |procedure, _evaluator|
|
||||||
procedure.publish!(procedure.administrateurs.first, generate(:published_path), procedure.lien_site_web)
|
procedure.path = generate(:published_path)
|
||||||
|
procedure.publish!
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
trait :archived do
|
trait :archived do
|
||||||
after(:build) do |procedure, _evaluator|
|
after(:build) do |procedure, _evaluator|
|
||||||
procedure.publish!(procedure.administrateurs.first, generate(:published_path), procedure.lien_site_web)
|
procedure.path = generate(:published_path)
|
||||||
|
procedure.publish!
|
||||||
procedure.archive!
|
procedure.archive!
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -163,14 +166,16 @@ FactoryBot.define do
|
||||||
# For now the behavior is the same than :archived
|
# For now the behavior is the same than :archived
|
||||||
# (it may be different in the future though)
|
# (it may be different in the future though)
|
||||||
after(:build) do |procedure, _evaluator|
|
after(:build) do |procedure, _evaluator|
|
||||||
procedure.publish!(procedure.administrateurs.first, generate(:published_path), procedure.lien_site_web)
|
procedure.path = generate(:published_path)
|
||||||
|
procedure.publish!
|
||||||
procedure.archive!
|
procedure.archive!
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
trait :hidden do
|
trait :hidden do
|
||||||
after(:build) do |procedure, _evaluator|
|
after(:build) do |procedure, _evaluator|
|
||||||
procedure.publish!(procedure.administrateurs.first, generate(:published_path), procedure.lien_site_web)
|
procedure.path = generate(:published_path)
|
||||||
|
procedure.publish!
|
||||||
procedure.hide!
|
procedure.hide!
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -547,12 +547,12 @@ describe Procedure do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#publish!' do
|
describe '#publish!' do
|
||||||
let(:procedure) { create(:procedure) }
|
let(:procedure) { create(:procedure, path: 'example-path') }
|
||||||
let(:now) { Time.zone.now.beginning_of_minute }
|
let(:now) { Time.zone.now.beginning_of_minute }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
Timecop.freeze(now)
|
Timecop.freeze(now)
|
||||||
procedure.publish!(procedure.administrateurs.first, "example-path", procedure.lien_site_web)
|
procedure.publish!
|
||||||
end
|
end
|
||||||
after { Timecop.return }
|
after { Timecop.return }
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ describe 'admin/procedures/show.html.haml', type: :view do
|
||||||
|
|
||||||
describe 'procedure is published' do
|
describe 'procedure is published' do
|
||||||
before do
|
before do
|
||||||
procedure.publish!(procedure.administrateurs.first, 'fake_path', procedure.lien_site_web)
|
procedure.publish!
|
||||||
procedure.reload
|
procedure.reload
|
||||||
render
|
render
|
||||||
end
|
end
|
||||||
|
@ -59,7 +59,7 @@ describe 'admin/procedures/show.html.haml', type: :view do
|
||||||
|
|
||||||
describe 'procedure is archived' do
|
describe 'procedure is archived' do
|
||||||
before do
|
before do
|
||||||
procedure.publish!(procedure.administrateurs.first, 'fake_path', procedure.lien_site_web)
|
procedure.publish!
|
||||||
procedure.archive!
|
procedure.archive!
|
||||||
procedure.reload
|
procedure.reload
|
||||||
render
|
render
|
||||||
|
|
Loading…
Reference in a new issue