Merge pull request #9445 from tchak/feat-add-champ-buttons
feat(type_de_champ): insert an add champ button after each type de champ
This commit is contained in:
commit
70b57257eb
8 changed files with 140 additions and 157 deletions
|
@ -14,13 +14,18 @@
|
||||||
|
|
||||||
.type-de-champ {
|
.type-de-champ {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background-color: #FAFDFF;
|
margin-bottom: $default-padding;
|
||||||
border: 1px solid $border-grey;
|
|
||||||
border-radius: 5px;
|
|
||||||
margin-bottom: $default-padding * 2;
|
|
||||||
box-shadow: 0px 2px 4px -4px;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
|
.type-de-champ-container {
|
||||||
|
width: 100%;
|
||||||
|
background-color: #FAFDFF;
|
||||||
|
border: 1px solid $border-grey;
|
||||||
|
border-radius: 5px;
|
||||||
|
margin-bottom: $default-padding;
|
||||||
|
box-shadow: 0px 2px 4px -4px;
|
||||||
|
}
|
||||||
|
|
||||||
.handle.icon {
|
.handle.icon {
|
||||||
width: 32px;
|
width: 32px;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
|
@ -71,6 +76,10 @@
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.last .type-de-champ-add-button.root {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
.head {
|
.head {
|
||||||
background-color: #FAFDFF;
|
background-color: #FAFDFF;
|
||||||
|
|
||||||
|
@ -91,10 +100,6 @@
|
||||||
&.section {
|
&.section {
|
||||||
padding: $default-spacer $default-spacer 0;
|
padding: $default-spacer $default-spacer 0;
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
|
|
||||||
input {
|
|
||||||
background-color: $white;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&.hr {
|
&.hr {
|
||||||
|
|
|
@ -2,13 +2,6 @@ class ApplicationComponent < ViewComponent::Base
|
||||||
include ViewComponent::Translatable
|
include ViewComponent::Translatable
|
||||||
include FlipperHelper
|
include FlipperHelper
|
||||||
|
|
||||||
# Takes a Hash of { class_name: boolean }.
|
|
||||||
# Returns truthy class names in an array. Array can be passed as-it in rails helpers,
|
|
||||||
# and is still manipulable if needed.
|
|
||||||
def class_names(class_names)
|
|
||||||
class_names.filter { _2 }.keys
|
|
||||||
end
|
|
||||||
|
|
||||||
def current_user
|
def current_user
|
||||||
controller.current_user
|
controller.current_user
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
class TypesDeChampEditor::AddChampButtonComponent < ApplicationComponent
|
class TypesDeChampEditor::AddChampButtonComponent < ApplicationComponent
|
||||||
def initialize(revision:, parent: nil, is_annotation: false)
|
def initialize(revision:, parent: nil, is_annotation: false, after_stable_id: nil)
|
||||||
@revision = revision
|
@revision = revision
|
||||||
@parent = parent
|
@parent = parent
|
||||||
@is_annotation = is_annotation
|
@is_annotation = is_annotation
|
||||||
|
@after_stable_id = after_stable_id
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -25,8 +26,7 @@ class TypesDeChampEditor::AddChampButtonComponent < ApplicationComponent
|
||||||
|
|
||||||
def button_options
|
def button_options
|
||||||
{
|
{
|
||||||
class: "button",
|
class: "fr-btn fr-btn--secondary fr-btn--icon-left fr-icon-add-line",
|
||||||
form: { class: @parent ? "add-to-block" : "add-to-root" },
|
|
||||||
method: :post,
|
method: :post,
|
||||||
params: {
|
params: {
|
||||||
type_de_champ: {
|
type_de_champ: {
|
||||||
|
@ -34,7 +34,7 @@ class TypesDeChampEditor::AddChampButtonComponent < ApplicationComponent
|
||||||
type_champ: TypeDeChamp.type_champs.fetch(:text),
|
type_champ: TypeDeChamp.type_champs.fetch(:text),
|
||||||
private: annotations? ? true : nil,
|
private: annotations? ? true : nil,
|
||||||
parent_stable_id: @parent&.stable_id,
|
parent_stable_id: @parent&.stable_id,
|
||||||
after_stable_id: ''
|
after_stable_id: @after_stable_id
|
||||||
}.compact
|
}.compact
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,8 +30,7 @@ class TypesDeChampEditor::ChampComponent < ApplicationComponent
|
||||||
controller: 'type-de-champ-editor',
|
controller: 'type-de-champ-editor',
|
||||||
type_de_champ_editor_move_url_value: move_admin_procedure_type_de_champ_path(procedure, type_de_champ.stable_id),
|
type_de_champ_editor_move_url_value: move_admin_procedure_type_de_champ_path(procedure, type_de_champ.stable_id),
|
||||||
type_de_champ_editor_move_up_url_value: move_up_admin_procedure_type_de_champ_path(procedure, type_de_champ.stable_id),
|
type_de_champ_editor_move_up_url_value: move_up_admin_procedure_type_de_champ_path(procedure, type_de_champ.stable_id),
|
||||||
type_de_champ_editor_move_down_url_value: move_down_admin_procedure_type_de_champ_path(procedure, type_de_champ.stable_id),
|
type_de_champ_editor_move_down_url_value: move_down_admin_procedure_type_de_champ_path(procedure, type_de_champ.stable_id)
|
||||||
type_de_champ_editor_type_de_champ_stable_id_value: type_de_champ.stable_id
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,117 +1,122 @@
|
||||||
%li.type-de-champ.flex.column.justify-start{ html_options }
|
%li.type-de-champ.flex.column.justify-start{ html_options }
|
||||||
.flex.justify-between.section.head.hr
|
.type-de-champ-container
|
||||||
.handle.small.icon-only.icon.move-handle{ title: "Déplacer le champ vers le haut ou vers le bas" }
|
.flex.justify-between.section.head.hr
|
||||||
|
.handle.small.icon-only.icon.move-handle{ title: "Déplacer le champ vers le haut ou vers le bas" }
|
||||||
|
|
||||||
- if coordinate.used_by_routing_rules?
|
- if coordinate.used_by_routing_rules?
|
||||||
.flex.align-center
|
.flex.align-center
|
||||||
%span
|
%span
|
||||||
utilisé pour
|
utilisé pour
|
||||||
= link_to('le routage', admin_procedure_groupe_instructeurs_path(revision.procedure_id, anchor: 'routing-rules'))
|
= link_to('le routage', admin_procedure_groupe_instructeurs_path(revision.procedure_id, anchor: 'routing-rules'))
|
||||||
- else
|
- else
|
||||||
.flex.justify-start.delete
|
.flex.justify-start.delete
|
||||||
= button_to type_de_champ_path, class: 'button small icon-only danger', method: :delete, form: { data: { turbo_confirm: 'Êtes vous sûr de vouloir supprimer ce champ ?' } } do
|
= button_to type_de_champ_path, class: 'fr-btn fr-btn--sm fr-btn--secondary fr-icon-delete-line', title: "Supprimer le champ", method: :delete, form: { data: { turbo_confirm: 'Êtes vous sûr de vouloir supprimer ce champ ?' } } do
|
||||||
.icon.delete
|
.icon.delete
|
||||||
%span.sr-only Supprimer
|
%span.sr-only Supprimer
|
||||||
|
|
||||||
- if @errors.present?
|
- if @errors.present?
|
||||||
.types-de-champ-errors
|
.types-de-champ-errors
|
||||||
= @errors
|
= @errors
|
||||||
|
|
||||||
.flex.justify-start.section.ml-1
|
.flex.justify-start.section.ml-1
|
||||||
= form_for(type_de_champ, form_options) do |form|
|
= form_for(type_de_champ, form_options) do |form|
|
||||||
.flex.justify-start
|
.flex.justify-start
|
||||||
.flex.justify-start.width-33
|
.flex.justify-start.width-33
|
||||||
.flex.justify-start.column
|
.flex.justify-start.column
|
||||||
%button.move-up.cell.mb-1{ move_button_options(:up) }
|
%button.move-up.cell.mb-1{ move_button_options(:up) }
|
||||||
.icon.arrow-up.small
|
.icon.arrow-up.small
|
||||||
%span.sr-only Déplacer le champ vers le haut
|
%span.sr-only Déplacer le champ vers le haut
|
||||||
%button.move-down.cell{ move_button_options(:down) }
|
%button.move-down.cell{ move_button_options(:down) }
|
||||||
.icon.arrow-down.small
|
.icon.arrow-down.small
|
||||||
%span.sr-only Déplacer le champ vers le bas
|
%span.sr-only Déplacer le champ vers le bas
|
||||||
.cell.flex.justify-start.column.flex-grow
|
.cell.flex.justify-start.column.flex-grow
|
||||||
= form.label :type_champ, "Type de champ", for: dom_id(type_de_champ, :type_champ)
|
= form.label :type_champ, "Type de champ", for: dom_id(type_de_champ, :type_champ)
|
||||||
= form.select :type_champ, grouped_options_for_select(types_of_type_de_champ, type_de_champ.type_champ), {}, class: 'small-margin small inline width-100', id: dom_id(type_de_champ, :type_champ), disabled: coordinate.used_by_routing_rules?
|
= form.select :type_champ, grouped_options_for_select(types_of_type_de_champ, type_de_champ.type_champ), {}, class: 'fr-select small-margin small inline width-100', id: dom_id(type_de_champ, :type_champ), disabled: coordinate.used_by_routing_rules?
|
||||||
.flex.column.justify-start.flex-grow
|
|
||||||
.cell
|
|
||||||
.flex.align-center
|
|
||||||
= form.label :libelle, "Libellé du champ", class: 'flex-grow', for: dom_id(type_de_champ, :libelle)
|
|
||||||
- if can_be_mandatory?
|
|
||||||
.cell.flex.align-center
|
|
||||||
= form.check_box :mandatory, class: 'small-margin small', id: dom_id(type_de_champ, :mandatory)
|
|
||||||
= form.label :mandatory, "Champ obligatoire", for: dom_id(type_de_champ, :mandatory)
|
|
||||||
= form.text_field :libelle, class: 'small-margin small width-100', id: dom_id(type_de_champ, :libelle), data: input_autofocus
|
|
||||||
- if type_de_champ.header_section?
|
|
||||||
%p
|
|
||||||
%small Nous numérotons automatiquement les titres lorsqu’aucun de vos titres ne commence par un chiffre.
|
|
||||||
|
|
||||||
- if !type_de_champ.header_section? && !type_de_champ.titre_identite?
|
|
||||||
.cell.mt-1
|
|
||||||
= form.label :description, "Description du champ (optionnel)", for: dom_id(type_de_champ, :description)
|
|
||||||
= form.text_area :description, class: 'small-margin small width-100', rows: 3, id: dom_id(type_de_champ, :description)
|
|
||||||
- if type_de_champ.header_section?
|
|
||||||
.cell.mt-1
|
|
||||||
= render TypesDeChampEditor::HeaderSectionComponent.new(form: form, tdc: type_de_champ, upper_tdcs: @upper_coordinates.map(&:type_de_champ))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.flex.justify-start.mt-1
|
|
||||||
- if type_de_champ.drop_down_list?
|
|
||||||
.flex.column.justify-start.width-33
|
|
||||||
.cell
|
|
||||||
= form.label :drop_down_list_value, "Options de la liste", for: dom_id(type_de_champ, :drop_down_list_value)
|
|
||||||
= form.text_area :drop_down_list_value, class: 'small-margin small width-100', rows: 7, id: dom_id(type_de_champ, :drop_down_list_value)
|
|
||||||
- if type_de_champ.simple_drop_down_list?
|
|
||||||
.cell
|
|
||||||
= form.label :drop_down_other, for: dom_id(type_de_champ, :drop_down_other) do
|
|
||||||
Proposer une option « autre » avec un texte libre
|
|
||||||
= form.check_box :drop_down_other, class: "small-margin small", id: dom_id(type_de_champ, :drop_down_other)
|
|
||||||
|
|
||||||
- if type_de_champ.linked_drop_down_list?
|
|
||||||
.flex.column.justify-start.flex-grow
|
.flex.column.justify-start.flex-grow
|
||||||
.cell
|
.cell
|
||||||
= form.label :drop_down_secondary_libelle, "Libellé du champ secondaire", class: 'flex-grow', for: dom_id(type_de_champ, :drop_down_secondary_libelle)
|
.flex.align-center
|
||||||
= form.text_field :drop_down_secondary_libelle, class: 'small-margin small width-100', id: dom_id(type_de_champ, :drop_down_secondary_libelle)
|
= form.label :libelle, "Libellé du champ", class: 'flex-grow', for: dom_id(type_de_champ, :libelle)
|
||||||
.cell.mt-1
|
- if can_be_mandatory?
|
||||||
= form.label :drop_down_secondary_description, "Description du champ secondaire (optionnel)", for: dom_id(type_de_champ, :drop_down_secondary_description)
|
.cell.flex.align-center
|
||||||
= form.text_area :drop_down_secondary_description, class: 'small-margin small width-100', rows: 3, id: dom_id(type_de_champ, :drop_down_secondary_description)
|
= form.check_box :mandatory, class: 'small-margin small', id: dom_id(type_de_champ, :mandatory)
|
||||||
- if type_de_champ.piece_justificative?
|
= form.label :mandatory, "Champ obligatoire", for: dom_id(type_de_champ, :mandatory)
|
||||||
.cell
|
= form.text_field :libelle, class: 'fr-input small-margin small width-100', id: dom_id(type_de_champ, :libelle), data: input_autofocus
|
||||||
= form.label :piece_justificative_template, "Modèle", for: dom_id(type_de_champ, :piece_justificative_template)
|
- if type_de_champ.header_section?
|
||||||
= render Attachment::EditComponent.new(**piece_justificative_template_options)
|
%p
|
||||||
|
%small Nous numérotons automatiquement les titres lorsqu’aucun de vos titres ne commence par un chiffre.
|
||||||
|
|
||||||
- if type_de_champ.titre_identite?
|
- if !type_de_champ.header_section? && !type_de_champ.titre_identite?
|
||||||
%p Dans le cadre de la RGPD, le titre d’identité sera supprimé lors de l’acceptation du dossier
|
.cell.mt-1
|
||||||
- elsif procedure.piece_justificative_multiple?
|
= form.label :description, "Description du champ (optionnel)", for: dom_id(type_de_champ, :description)
|
||||||
%p Les usagers pourront envoyer plusieurs fichiers si nécessaire.
|
= form.text_area :description, class: 'fr-input small-margin small width-100', rows: 3, id: dom_id(type_de_champ, :description)
|
||||||
- if type_de_champ.carte?
|
- if type_de_champ.header_section?
|
||||||
- type_de_champ.editable_options.each do |slice|
|
.cell.mt-1
|
||||||
|
= render TypesDeChampEditor::HeaderSectionComponent.new(form: form, tdc: type_de_champ, upper_tdcs: @upper_coordinates.map(&:type_de_champ))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.flex.justify-start.mt-1
|
||||||
|
- if type_de_champ.drop_down_list?
|
||||||
|
.flex.column.justify-start.width-33
|
||||||
|
.cell
|
||||||
|
= form.label :drop_down_list_value, "Options de la liste", for: dom_id(type_de_champ, :drop_down_list_value)
|
||||||
|
= form.text_area :drop_down_list_value, class: 'fr-input small-margin small width-100', rows: 7, id: dom_id(type_de_champ, :drop_down_list_value)
|
||||||
|
- if type_de_champ.simple_drop_down_list?
|
||||||
|
.cell
|
||||||
|
= form.label :drop_down_other, for: dom_id(type_de_champ, :drop_down_other) do
|
||||||
|
Proposer une option « autre » avec un texte libre
|
||||||
|
= form.check_box :drop_down_other, class: "small-margin small", id: dom_id(type_de_champ, :drop_down_other)
|
||||||
|
|
||||||
|
- if type_de_champ.linked_drop_down_list?
|
||||||
|
.flex.column.justify-start.flex-grow
|
||||||
|
.cell
|
||||||
|
= form.label :drop_down_secondary_libelle, "Libellé du champ secondaire", class: 'flex-grow', for: dom_id(type_de_champ, :drop_down_secondary_libelle)
|
||||||
|
= form.text_field :drop_down_secondary_libelle, class: 'fr-input small-margin small width-100', id: dom_id(type_de_champ, :drop_down_secondary_libelle)
|
||||||
|
.cell.mt-1
|
||||||
|
= form.label :drop_down_secondary_description, "Description du champ secondaire (optionnel)", for: dom_id(type_de_champ, :drop_down_secondary_description)
|
||||||
|
= form.text_area :drop_down_secondary_description, class: 'fr-input small-margin small width-100', rows: 3, id: dom_id(type_de_champ, :drop_down_secondary_description)
|
||||||
|
- if type_de_champ.piece_justificative?
|
||||||
.cell
|
.cell
|
||||||
.carte-options
|
= form.label :piece_justificative_template, "Modèle", for: dom_id(type_de_champ, :piece_justificative_template)
|
||||||
= form.fields_for :editable_options do |form|
|
= render Attachment::EditComponent.new(**piece_justificative_template_options)
|
||||||
- slice.each do |(name, checked)|
|
|
||||||
= form.label name, for: dom_id(type_de_champ, "layer_#{name}") do
|
|
||||||
= form.check_box name, checked: checked, class: 'small-margin small', id: dom_id(type_de_champ, "layer_#{name}")
|
|
||||||
= t(".layers.#{name}")
|
|
||||||
- if type_de_champ.explication?
|
|
||||||
.cell.width-66
|
|
||||||
= form.label :collapsible_explanation_enabled, for: dom_id(type_de_champ, :collapsible_explanation_enabled) do
|
|
||||||
Afficher un texte complementaire affichable au clic
|
|
||||||
= form.check_box :collapsible_explanation_enabled, class: "small-margin small", id: dom_id(type_de_champ, :collapsible_explanation_enabled)
|
|
||||||
- if form.object.collapsible_explanation_enabled?
|
|
||||||
= form.label :collapsible_explanation_text, for: dom_id(type_de_champ, :collapsible_explanation_text) do
|
|
||||||
= "Texte à afficher quand l'utiliser a choisi de l'afficher"
|
|
||||||
= form.text_area :collapsible_explanation_text, class: "small-margin small", id: dom_id(type_de_champ, :collapsible_explanation_text)
|
|
||||||
- if type_de_champ.textarea?
|
|
||||||
.cell
|
|
||||||
= form.label :character_limit, for: dom_id(type_de_champ, :character_limit) do
|
|
||||||
Spécifier un nombre maximal conseillé de caractères :
|
|
||||||
= form.select :character_limit, options_for_character_limit, id: dom_id(type_de_champ, :character_limit)
|
|
||||||
|
|
||||||
- if type_de_champ.block?
|
- if type_de_champ.titre_identite?
|
||||||
.flex.justify-start.section.ml-1
|
%p Dans le cadre de la RGPD, le titre d’identité sera supprimé lors de l’acceptation du dossier
|
||||||
.editor-block.flex-grow.cell
|
- elsif procedure.piece_justificative_multiple?
|
||||||
= render TypesDeChampEditor::BlockComponent.new(block: coordinate, coordinates: coordinate.revision_types_de_champ, upper_coordinates: @upper_coordinates)
|
%p Les usagers pourront envoyer plusieurs fichiers si nécessaire.
|
||||||
= render TypesDeChampEditor::AddChampButtonComponent.new(revision: coordinate.revision, parent: coordinate, is_annotation: coordinate.private?)
|
- if type_de_champ.carte?
|
||||||
|
- type_de_champ.editable_options.each do |slice|
|
||||||
|
.cell
|
||||||
|
.carte-options
|
||||||
|
= form.fields_for :editable_options do |form|
|
||||||
|
- slice.each do |(name, checked)|
|
||||||
|
= form.label name, for: dom_id(type_de_champ, "layer_#{name}") do
|
||||||
|
= form.check_box name, checked: checked, class: 'small-margin small', id: dom_id(type_de_champ, "layer_#{name}")
|
||||||
|
= t(".layers.#{name}")
|
||||||
|
- if type_de_champ.explication?
|
||||||
|
.cell.width-66
|
||||||
|
= form.label :collapsible_explanation_enabled, for: dom_id(type_de_champ, :collapsible_explanation_enabled) do
|
||||||
|
Afficher un texte complementaire affichable au clic
|
||||||
|
= form.check_box :collapsible_explanation_enabled, class: "small-margin small", id: dom_id(type_de_champ, :collapsible_explanation_enabled)
|
||||||
|
- if form.object.collapsible_explanation_enabled?
|
||||||
|
= form.label :collapsible_explanation_text, for: dom_id(type_de_champ, :collapsible_explanation_text) do
|
||||||
|
= "Texte à afficher quand l'utiliser a choisi de l'afficher"
|
||||||
|
= form.text_area :collapsible_explanation_text, class: "fr-input small-margin small", id: dom_id(type_de_champ, :collapsible_explanation_text)
|
||||||
|
- if type_de_champ.textarea?
|
||||||
|
.cell
|
||||||
|
= form.label :character_limit, for: dom_id(type_de_champ, :character_limit) do
|
||||||
|
Spécifier un nombre maximal conseillé de caractères :
|
||||||
|
= form.select :character_limit, options_for_character_limit, id: dom_id(type_de_champ, :character_limit), class: 'fr-select'
|
||||||
|
|
||||||
- if conditional_enabled?
|
- if type_de_champ.block?
|
||||||
= render(TypesDeChampEditor::ConditionsComponent.new(tdc: type_de_champ, upper_tdcs: @upper_coordinates.map(&:type_de_champ), procedure_id: procedure.id))
|
.flex.justify-start.section.ml-1
|
||||||
|
.editor-block.flex-grow.cell
|
||||||
|
= render TypesDeChampEditor::BlockComponent.new(block: coordinate, coordinates: coordinate.revision_types_de_champ, upper_coordinates: @upper_coordinates)
|
||||||
|
.type-de-champ-add-button{ id: dom_id(coordinate, :type_de_champ_add_button), class: class_names(hidden: !coordinate.empty?) }
|
||||||
|
= render TypesDeChampEditor::AddChampButtonComponent.new(revision: coordinate.revision, parent: coordinate, is_annotation: coordinate.private?)
|
||||||
|
|
||||||
|
- if conditional_enabled?
|
||||||
|
= render(TypesDeChampEditor::ConditionsComponent.new(tdc: type_de_champ, upper_tdcs: @upper_coordinates.map(&:type_de_champ), procedure_id: procedure.id))
|
||||||
|
|
||||||
|
.type-de-champ-add-button{ class: class_names(root: !coordinate.child?) }
|
||||||
|
= render TypesDeChampEditor::AddChampButtonComponent.new(revision: coordinate.revision, parent: coordinate&.parent, is_annotation: coordinate.private?, after_stable_id: type_de_champ.stable_id)
|
||||||
|
|
|
@ -7,7 +7,6 @@ import {
|
||||||
isTextInputElement,
|
isTextInputElement,
|
||||||
getConfig
|
getConfig
|
||||||
} from '@utils';
|
} from '@utils';
|
||||||
import { useIntersection } from 'stimulus-use';
|
|
||||||
import { AutoUpload } from '../shared/activestorage/auto-upload';
|
import { AutoUpload } from '../shared/activestorage/auto-upload';
|
||||||
import { ApplicationController } from './application_controller';
|
import { ApplicationController } from './application_controller';
|
||||||
|
|
||||||
|
@ -28,7 +27,6 @@ export class TypeDeChampEditorController extends ApplicationController {
|
||||||
declare readonly moveUrlValue: string;
|
declare readonly moveUrlValue: string;
|
||||||
declare readonly moveUpUrlValue: string;
|
declare readonly moveUpUrlValue: string;
|
||||||
declare readonly moveDownUrlValue: string;
|
declare readonly moveDownUrlValue: string;
|
||||||
declare readonly typeDeChampStableIdValue: string;
|
|
||||||
declare readonly isVisible: boolean;
|
declare readonly isVisible: boolean;
|
||||||
|
|
||||||
#latestPromise = Promise.resolve();
|
#latestPromise = Promise.resolve();
|
||||||
|
@ -36,8 +34,6 @@ export class TypeDeChampEditorController extends ApplicationController {
|
||||||
#inFlightForms: Map<HTMLFormElement, AbortController> = new Map();
|
#inFlightForms: Map<HTMLFormElement, AbortController> = new Map();
|
||||||
|
|
||||||
connect() {
|
connect() {
|
||||||
useIntersection(this, { threshold: 0.6 });
|
|
||||||
|
|
||||||
this.#latestPromise = Promise.resolve();
|
this.#latestPromise = Promise.resolve();
|
||||||
this.on('change', (event) => this.onChange(event));
|
this.on('change', (event) => this.onChange(event));
|
||||||
this.on('input', (event) => this.onInput(event));
|
this.on('input', (event) => this.onInput(event));
|
||||||
|
@ -62,10 +58,6 @@ export class TypeDeChampEditorController extends ApplicationController {
|
||||||
this.requestSubmitForm(form);
|
this.requestSubmitForm(form);
|
||||||
}
|
}
|
||||||
|
|
||||||
appear() {
|
|
||||||
this.updateAfterId();
|
|
||||||
}
|
|
||||||
|
|
||||||
private onChange(event: Event) {
|
private onChange(event: Event) {
|
||||||
const target = event.target as HTMLElement & { form?: HTMLFormElement };
|
const target = event.target as HTMLElement & { form?: HTMLFormElement };
|
||||||
|
|
||||||
|
@ -144,28 +136,8 @@ export class TypeDeChampEditorController extends ApplicationController {
|
||||||
this.#inFlightForms.set(form, controller);
|
this.#inFlightForms.set(form, controller);
|
||||||
return controller;
|
return controller;
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateAfterId() {
|
|
||||||
const parent = this.element.closest<HTMLElement>(
|
|
||||||
'.editor-block, .editor-root'
|
|
||||||
);
|
|
||||||
if (parent) {
|
|
||||||
const selector = parent.classList.contains('editor-block')
|
|
||||||
? '.add-to-block'
|
|
||||||
: '.add-to-root';
|
|
||||||
const input = parent.querySelector<HTMLInputElement>(
|
|
||||||
`${selector} ${AFTER_STABLE_ID_INPUT_SELECTOR}`
|
|
||||||
);
|
|
||||||
if (input) {
|
|
||||||
input.value = this.typeDeChampStableIdValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const AFTER_STABLE_ID_INPUT_SELECTOR =
|
|
||||||
'input[name="type_de_champ[after_stable_id]"]';
|
|
||||||
|
|
||||||
function createForm(action: string, method: string) {
|
function createForm(action: string, method: string) {
|
||||||
const form = document.createElement('form');
|
const form = document.createElement('form');
|
||||||
form.action = action;
|
form.action = action;
|
||||||
|
|
|
@ -25,6 +25,10 @@ class ProcedureRevisionTypeDeChamp < ApplicationRecord
|
||||||
siblings.last == self
|
siblings.last == self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def empty?
|
||||||
|
revision_types_de_champ.empty?
|
||||||
|
end
|
||||||
|
|
||||||
def siblings
|
def siblings
|
||||||
if parent_id.present?
|
if parent_id.present?
|
||||||
revision.revision_types_de_champ.where(parent_id: parent_id).ordered
|
revision.revision_types_de_champ.where(parent_id: parent_id).ordered
|
||||||
|
|
|
@ -26,3 +26,8 @@
|
||||||
- render TypesDeChampEditor::EstimatedFillDurationComponent.new(revision: @coordinate.revision, is_annotation: @coordinate.private?)
|
- render TypesDeChampEditor::EstimatedFillDurationComponent.new(revision: @coordinate.revision, is_annotation: @coordinate.private?)
|
||||||
|
|
||||||
= turbo_stream.dispatch 'sortable:sort'
|
= turbo_stream.dispatch 'sortable:sort'
|
||||||
|
|
||||||
|
- if @created&.coordinate&.child?
|
||||||
|
= turbo_stream.hide dom_id(@created.coordinate.parent, :type_de_champ_add_button)
|
||||||
|
- elsif @destroyed&.child? && @destroyed.parent.empty?
|
||||||
|
= turbo_stream.show dom_id(@destroyed.parent, :type_de_champ_add_button)
|
||||||
|
|
Loading…
Reference in a new issue