Merge pull request #10117 from tchak/refactor-readable-champ-project
refactor(champs): if champ not found - build it
This commit is contained in:
commit
659f15fcd2
26 changed files with 129 additions and 120 deletions
|
@ -3,15 +3,17 @@ class Dossiers::ChampsRowsShowComponent < ApplicationComponent
|
||||||
attr_reader :seen_at
|
attr_reader :seen_at
|
||||||
|
|
||||||
def initialize(champs:, profile:, seen_at:)
|
def initialize(champs:, profile:, seen_at:)
|
||||||
@champs = champs
|
@champs, @profile, @seen_at = champs, profile, seen_at
|
||||||
@seen_at = seen_at
|
|
||||||
@profile = profile
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def updated_after_deposer?(champ)
|
private
|
||||||
return false if champ.dossier.depose_at.blank?
|
|
||||||
|
|
||||||
champ.updated_at > champ.dossier.depose_at
|
def updated_at_after_deposer(champ)
|
||||||
|
return if champ.dossier.depose_at.blank?
|
||||||
|
|
||||||
|
if champ.updated_at > champ.dossier.depose_at
|
||||||
|
champ.updated_at
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def number_with_html_delimiter(num)
|
def number_with_html_delimiter(num)
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
- each_champ do |champ|
|
- each_champ do |champ|
|
||||||
- if champ.repetition?
|
- if champ.repetition?
|
||||||
- types_de_champ = champ.dossier.revision.children_of(champ.type_de_champ)
|
- types_de_champ = champ.dossier.revision.children_of(champ.type_de_champ)
|
||||||
- champs_by_stable_id_with_row = champ.dossier.champs_by_stable_id_with_row
|
- champ.row_ids.each.with_index(1) do |row_id, row_number|
|
||||||
- champ.row_ids.each.with_index do |row_id, i|
|
|
||||||
.fr-background-alt--grey.fr-p-2w.fr-my-3w.fr-ml-2w.champ-repetition
|
.fr-background-alt--grey.fr-p-2w.fr-my-3w.fr-ml-2w.champ-repetition
|
||||||
%p.font-weight-bold= "#{champ.libelle} #{i + 1} :"
|
%p.font-weight-bold= "#{champ.libelle} #{row_number} :"
|
||||||
= render ViewableChamp::SectionComponent.new(types_de_champ:, champs_by_stable_id_with_row:, row_id:, demande_seen_at: seen_at, profile:)
|
= render ViewableChamp::SectionComponent.new(dossier: champ.dossier, types_de_champ:, row_id:, demande_seen_at: seen_at, profile:)
|
||||||
|
|
||||||
- else
|
- else
|
||||||
= render Dossiers::RowShowComponent.new(label: champ.libelle, seen_at:, profile:, content_class: champ.type_champ, updated_at: updated_after_deposer?(champ) ? champ.updated_at : nil) do |c|
|
= render Dossiers::RowShowComponent.new(label: champ.libelle, seen_at:, profile:, content_class: champ.type_champ, updated_at: updated_at_after_deposer(champ)) do |c|
|
||||||
- if champ.blank?
|
- if champ.blank?
|
||||||
- c.with_blank do
|
- c.with_blank do
|
||||||
= t(blank_key(champ))
|
= t(blank_key(champ))
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
|
|
||||||
|
|
||||||
.repetition{ id: dom_id(@champ, :rows) }
|
.repetition{ id: dom_id(@champ, :rows) }
|
||||||
- @champ.row_ids.each do |row_id|
|
- @champ.row_ids.each.with_index(1) do |row_id, row_number|
|
||||||
= render EditableChamp::RepetitionRowComponent.new(form: @form, champ: @champ, row_id:, seen_at: @seen_at)
|
= render EditableChamp::RepetitionRowComponent.new(form: @form, dossier: @champ.dossier, type_de_champ: @champ.type_de_champ, row_id:, row_number:, seen_at: @seen_at)
|
||||||
|
|
||||||
.actions
|
.actions
|
||||||
= render NestedForms::OwnedButtonComponent.new(formaction: champs_repetition_path(@champ.id), http_method: :create, opt: { class: "fr-btn fr-btn--secondary fr-btn--icon-left fr-icon-add-circle-line fr-mb-3w", title: t(".add_title", libelle: @champ.libelle), id: dom_id(@champ, :create_repetition)}) do
|
= render NestedForms::OwnedButtonComponent.new(formaction: champs_repetition_path(@champ.dossier, @champ.stable_id), http_method: :create, opt: { class: "fr-btn fr-btn--secondary fr-btn--icon-left fr-icon-add-circle-line fr-mb-3w", title: t(".add_title", libelle: @champ.libelle), id: dom_id(@champ, :create_repetition)}) do
|
||||||
= t(".add", libelle: @champ.libelle)
|
= t(".add", libelle: @champ.libelle)
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
class EditableChamp::RepetitionRowComponent < ApplicationComponent
|
class EditableChamp::RepetitionRowComponent < ApplicationComponent
|
||||||
def initialize(form:, champ:, row_id:, seen_at: nil)
|
def initialize(form:, dossier:, type_de_champ:, row_id:, row_number:, seen_at: nil)
|
||||||
@form, @champ, @row_id, @seen_at = form, champ, row_id, seen_at
|
@form, @dossier, @type_de_champ, @row_id, @row_number, @seen_at = form, dossier, type_de_champ, row_id, row_number, seen_at
|
||||||
|
@types_de_champ = dossier.revision.children_of(type_de_champ)
|
||||||
@types_de_champ = champ.dossier.revision.children_of(champ.type_de_champ)
|
|
||||||
@champs_by_stable_id_with_row = champ.dossier.champs_by_stable_id_with_row
|
|
||||||
@row_number = champ.row_ids.find_index(row_id)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
attr_reader :row_id, :row_number
|
attr_reader :row_id, :row_number
|
||||||
|
@ -12,6 +9,6 @@ class EditableChamp::RepetitionRowComponent < ApplicationComponent
|
||||||
private
|
private
|
||||||
|
|
||||||
def section_component
|
def section_component
|
||||||
EditableChamp::SectionComponent.new(types_de_champ: @types_de_champ, champs_by_stable_id_with_row: @champs_by_stable_id_with_row, row_id:)
|
EditableChamp::SectionComponent.new(dossier: @dossier, types_de_champ: @types_de_champ, row_id:)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
.row{ id: "safe-row-selector-#{row_id}" }
|
.row{ id: "safe-row-selector-#{row_id}" }
|
||||||
- if @types_de_champ.size > 1
|
- if @types_de_champ.size > 1
|
||||||
%fieldset
|
%fieldset
|
||||||
%legend.block-id= "#{@champ.libelle} "
|
%legend.block-id= "#{@type_de_champ.libelle} "
|
||||||
= render section_component
|
= render section_component
|
||||||
- else
|
- else
|
||||||
= render section_component
|
= render section_component
|
||||||
|
|
||||||
.flex.row-reverse
|
.flex.row-reverse
|
||||||
= render NestedForms::OwnedButtonComponent.new(formaction: champs_repetition_path(@champ.id, row_id:), http_method: :delete, opt: { class: "fr-btn fr-btn--sm fr-btn--tertiary fr-text-action-high--red-marianne", title: t(".delete_title", row_number:)}) do
|
= render NestedForms::OwnedButtonComponent.new(formaction: champs_repetition_path(@dossier, @type_de_champ.stable_id, row_id:), http_method: :delete, opt: { class: "fr-btn fr-btn--sm fr-btn--tertiary fr-text-action-high--red-marianne", title: t(".delete_title", row_number:)}) do
|
||||||
= t(".delete")
|
= t(".delete")
|
||||||
|
|
|
@ -2,9 +2,9 @@ class EditableChamp::SectionComponent < ApplicationComponent
|
||||||
include ApplicationHelper
|
include ApplicationHelper
|
||||||
include TreeableConcern
|
include TreeableConcern
|
||||||
|
|
||||||
def initialize(nodes: nil, types_de_champ: nil, row_id: nil, champs_by_stable_id_with_row:)
|
def initialize(dossier:, nodes: nil, types_de_champ: nil, row_id: nil)
|
||||||
nodes ||= to_tree(types_de_champ:)
|
nodes ||= to_tree(types_de_champ:)
|
||||||
@champs_by_stable_id_with_row = champs_by_stable_id_with_row
|
@dossier = dossier
|
||||||
@row_id = row_id
|
@row_id = row_id
|
||||||
@nodes = to_fieldset(nodes:)
|
@nodes = to_fieldset(nodes:)
|
||||||
end
|
end
|
||||||
|
@ -15,7 +15,7 @@ class EditableChamp::SectionComponent < ApplicationComponent
|
||||||
|
|
||||||
def header_section
|
def header_section
|
||||||
node = @nodes.first
|
node = @nodes.first
|
||||||
champ_for_type_de_champ(node) if node.is_a?(TypeDeChamp) && node.header_section?
|
@dossier.project_champ(node, @row_id) if node.is_a?(TypeDeChamp) && node.header_section?
|
||||||
end
|
end
|
||||||
|
|
||||||
def splitted_tail
|
def splitted_tail
|
||||||
|
@ -38,21 +38,17 @@ class EditableChamp::SectionComponent < ApplicationComponent
|
||||||
when EditableChamp::SectionComponent
|
when EditableChamp::SectionComponent
|
||||||
[node, nil]
|
[node, nil]
|
||||||
else
|
else
|
||||||
[nil, champ_for_type_de_champ(node)]
|
[nil, @dossier.project_champ(node, @row_id)]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def to_fieldset(nodes:)
|
def to_fieldset(nodes:)
|
||||||
nodes.map { _1.is_a?(Array) ? EditableChamp::SectionComponent.new(nodes: _1, row_id: @row_id, champs_by_stable_id_with_row: @champs_by_stable_id_with_row) : _1 }
|
nodes.map { _1.is_a?(Array) ? EditableChamp::SectionComponent.new(dossier: @dossier, nodes: _1, row_id: @row_id) : _1 }
|
||||||
end
|
end
|
||||||
|
|
||||||
def first_champ_is_an_header_section?
|
def first_champ_is_an_header_section?
|
||||||
header_section.present?
|
header_section.present?
|
||||||
end
|
end
|
||||||
|
|
||||||
def champ_for_type_de_champ(type_de_champ)
|
|
||||||
@champs_by_stable_id_with_row[[@row_id, type_de_champ.stable_id].compact]
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,25 +2,25 @@ class ViewableChamp::SectionComponent < ApplicationComponent
|
||||||
include ApplicationHelper
|
include ApplicationHelper
|
||||||
include TreeableConcern
|
include TreeableConcern
|
||||||
|
|
||||||
def initialize(nodes: nil, types_de_champ: nil, row_id: nil, demande_seen_at:, profile:, champs_by_stable_id_with_row:)
|
def initialize(dossier:, nodes: nil, types_de_champ: nil, row_id: nil, demande_seen_at:, profile:)
|
||||||
@demande_seen_at, @profile, @row_id, @champs_by_stable_id_with_row = demande_seen_at, profile, row_id, champs_by_stable_id_with_row
|
@dossier, @demande_seen_at, @profile, @row_id = dossier, demande_seen_at, profile, row_id
|
||||||
nodes ||= to_tree(types_de_champ:)
|
nodes ||= to_tree(types_de_champ:)
|
||||||
@nodes = to_sections(nodes:)
|
@nodes = to_sections(nodes:)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
def section_id
|
def section_id
|
||||||
@section_id ||= header_section ? dom_id(header_section, :content) : SecureRandom.uuid
|
@section_id ||= header_section ? dom_id(header_section, :content) : SecureRandom.uuid
|
||||||
end
|
end
|
||||||
|
|
||||||
def header_section
|
def header_section
|
||||||
maybe_header_section = @nodes.first
|
node = @nodes.first
|
||||||
if maybe_header_section.is_a?(TypeDeChamp) && maybe_header_section.header_section?
|
@dossier.project_champ(node, @row_id) if node.is_a?(TypeDeChamp) && node.header_section?
|
||||||
champ_for_type_de_champ(maybe_header_section)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def champs
|
def champs
|
||||||
tail.filter_map { _1.is_a?(TypeDeChamp) ? champ_for_type_de_champ(_1) : nil }
|
tail.filter_map { _1.is_a?(TypeDeChamp) ? @dossier.project_champ(_1, @row_id) : nil }
|
||||||
end
|
end
|
||||||
|
|
||||||
def sections
|
def sections
|
||||||
|
@ -28,14 +28,14 @@ class ViewableChamp::SectionComponent < ApplicationComponent
|
||||||
end
|
end
|
||||||
|
|
||||||
def tail
|
def tail
|
||||||
return @nodes if header_section.blank?
|
return @nodes if header_section.nil?
|
||||||
_, *rest_of_champ = @nodes
|
_, *rest_of_champ = @nodes
|
||||||
|
|
||||||
rest_of_champ
|
rest_of_champ
|
||||||
end
|
end
|
||||||
|
|
||||||
def reset_tag_for_depth
|
def reset_tag_for_depth
|
||||||
return if !header_section
|
return if header_section.nil?
|
||||||
|
|
||||||
"reset-h#{header_section.level + 1}"
|
"reset-h#{header_section.level + 1}"
|
||||||
end
|
end
|
||||||
|
@ -49,10 +49,6 @@ class ViewableChamp::SectionComponent < ApplicationComponent
|
||||||
private
|
private
|
||||||
|
|
||||||
def to_sections(nodes:)
|
def to_sections(nodes:)
|
||||||
nodes.map { _1.is_a?(Array) ? ViewableChamp::SectionComponent.new(nodes: _1, demande_seen_at: @demande_seen_at, profile: @profile, champs_by_stable_id_with_row: @champs_by_stable_id_with_row, row_id: @row_id) : _1 }
|
nodes.map { _1.is_a?(Array) ? ViewableChamp::SectionComponent.new(dossier: @dossier, nodes: _1, demande_seen_at: @demande_seen_at, profile: @profile, row_id: @row_id) : _1 }
|
||||||
end
|
|
||||||
|
|
||||||
def champ_for_type_de_champ(type_de_champ)
|
|
||||||
@champs_by_stable_id_with_row[[@row_id, type_de_champ.stable_id].compact]
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
= tag.div(class: class_names(reset_tag_for_depth => true, "fr-my-2w" => !first_level?), 'data-controller': 'expand') do
|
= tag.div(class: class_names(reset_tag_for_depth => true, "fr-my-2w" => !first_level?), 'data-controller': 'expand') do
|
||||||
- if header_section
|
- if header_section
|
||||||
%div{ class: class_names(flex: true, "top-bordered" => first_level?) }
|
%div{ class: class_names(flex: true, "top-bordered" => first_level?) }
|
||||||
= render EditableChamp::HeaderSectionComponent.new(champ: header_section, html_class: {' fr-m-0 fr-text--md fr-px-4v flex-grow' => true, "fr-text-action-high--blue-france" => header_section.level == 1, 'fr-py-2w' => first_level?, 'fr-py-1v' => !first_level?})
|
= render EditableChamp::HeaderSectionComponent.new(champ: header_section, html_class: { 'fr-m-0 fr-text--md fr-px-4v flex-grow': true, "fr-text-action-high--blue-france fr-py-2w": first_level?, 'fr-py-1v': !first_level? })
|
||||||
- if ![champs, sections].map(&:empty?).all? && first_level?
|
- if ![champs, sections].map(&:empty?).all? && first_level?
|
||||||
%button{ type: "button", aria: { controls: section_id, "expanded": "true", label: t('.toggle_section', section: header_section.libelle) }, href: section_id, 'data-action': 'click->expand#toggle', class: "fr-btn fr-btn--tertiary-no-outline" }
|
%button{ type: "button", aria: { controls: section_id, "expanded": "true", label: t('.toggle_section', section: header_section.libelle) }, href: section_id, 'data-action': 'click->expand#toggle', class: "fr-btn fr-btn--tertiary-no-outline" }
|
||||||
%i.fr-icon-arrow-up-s-line{ 'aria-hidden': 'true', 'data-expand-target': 'icon' }
|
%i.fr-icon-arrow-up-s-line{ 'aria-hidden': 'true', 'data-expand-target': 'icon' }
|
||||||
|
|
||||||
%div{ id: section_id, 'data-expand-target': 'content' }
|
%div{ id: section_id, 'data-expand-target': 'content' }
|
||||||
- if !champs.empty?
|
- if !champs.empty?
|
||||||
= render Dossiers::ChampsRowsShowComponent.new(champs: champs, seen_at: @demande_seen_at, profile: @profile)
|
= render Dossiers::ChampsRowsShowComponent.new(champs:, seen_at: @demande_seen_at, profile: @profile)
|
||||||
|
|
||||||
- sections.each do |section|
|
- sections.each do |section|
|
||||||
= render section
|
= render section
|
||||||
|
|
|
@ -2,16 +2,29 @@ class Champs::RepetitionController < ApplicationController
|
||||||
before_action :authenticate_logged_user!
|
before_action :authenticate_logged_user!
|
||||||
|
|
||||||
def add
|
def add
|
||||||
@champ = policy_scope(Champ).includes(:champs).find(params[:champ_id])
|
@champ = find_champ
|
||||||
row = @champ.add_row(@champ.dossier.revision)
|
row = @champ.add_row(@champ.dossier.revision)
|
||||||
@first_champ_id = row.map(&:focusable_input_id).compact.first
|
@first_champ_id = row.map(&:focusable_input_id).compact.first
|
||||||
@row_id = row.first&.row_id
|
@row_id = row.first&.row_id
|
||||||
|
@row_number = @champ.row_ids.find_index(@row_id) + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
def remove
|
def remove
|
||||||
@champ = policy_scope(Champ).includes(:champs).find(params[:champ_id])
|
@champ = find_champ
|
||||||
@champ.champs.where(row_id: params[:row_id]).destroy_all
|
@champ.champs.where(row_id: params[:row_id]).destroy_all
|
||||||
@champ.reload
|
@champ.reload
|
||||||
@row_id = params[:row_id]
|
@row_id = params[:row_id]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def find_champ
|
||||||
|
if params[:champ_id].present?
|
||||||
|
policy_scope(Champ).includes(:champs).find(params[:champ_id])
|
||||||
|
else
|
||||||
|
policy_scope(Champ)
|
||||||
|
.includes(:champs, :type_de_champ)
|
||||||
|
.find_by!(dossier_id: params[:dossier_id], type_de_champ: { stable_id: params[:stable_id] })
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -160,7 +160,7 @@ class Champ < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def input_group_id
|
def input_group_id
|
||||||
"champ-#{html_id}"
|
html_id
|
||||||
end
|
end
|
||||||
|
|
||||||
def input_id
|
def input_id
|
||||||
|
@ -258,7 +258,7 @@ class Champ < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def html_id
|
def html_id
|
||||||
"champ-#{stable_id}-#{id}"
|
row_id.present? ? "champ-#{stable_id}-#{row_id}" : "champ-#{stable_id}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def needs_dossier_id?
|
def needs_dossier_id?
|
||||||
|
|
|
@ -1,14 +1,4 @@
|
||||||
class Champs::HeaderSectionChamp < Champ
|
class Champs::HeaderSectionChamp < Champ
|
||||||
def level
|
|
||||||
if parent.present?
|
|
||||||
header_section_level_value.to_i + parent.current_section_level(dossier.revision)
|
|
||||||
elsif header_section_level_value
|
|
||||||
header_section_level_value.to_i
|
|
||||||
else
|
|
||||||
0
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def search_terms
|
def search_terms
|
||||||
# The user cannot enter any information here so it doesn’t make much sense to search
|
# The user cannot enter any information here so it doesn’t make much sense to search
|
||||||
end
|
end
|
||||||
|
@ -16,4 +6,8 @@ class Champs::HeaderSectionChamp < Champ
|
||||||
def libelle_with_section_index?
|
def libelle_with_section_index?
|
||||||
libelle =~ /^\d/
|
libelle =~ /^\d/
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def level
|
||||||
|
type_de_champ.level_for_revision(dossier.revision)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -42,7 +42,7 @@ class Champs::RepetitionChamp < Champ
|
||||||
|
|
||||||
def rows_for_export
|
def rows_for_export
|
||||||
champs = dossier.champs_by_stable_id_with_row
|
champs = dossier.champs_by_stable_id_with_row
|
||||||
row_ids.each.with_index(1).map do |row_id, index|
|
row_ids.map.with_index(1) do |row_id, index|
|
||||||
Champs::RepetitionChamp::Row.new(index: index, row_id:, dossier_id: dossier_id.to_s, champs:)
|
Champs::RepetitionChamp::Row.new(index: index, row_id:, dossier_id: dossier_id.to_s, champs:)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1410,6 +1410,16 @@ class Dossier < ApplicationRecord
|
||||||
revision.revision_types_de_champ_private.present?
|
revision.revision_types_de_champ_private.present?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def project_champ(type_de_champ, row_id)
|
||||||
|
stable_id_with_row = [row_id, type_de_champ.stable_id].compact
|
||||||
|
champ = champs.find { _1.stable_id_with_row == stable_id_with_row }
|
||||||
|
if champ.nil?
|
||||||
|
type_de_champ.build_champ(dossier: self, row_id:)
|
||||||
|
else
|
||||||
|
champ
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def create_missing_traitemets
|
def create_missing_traitemets
|
||||||
|
|
|
@ -145,7 +145,7 @@ class TypeDeChamp < ApplicationRecord
|
||||||
has_one :revision, through: :revision_type_de_champ
|
has_one :revision, through: :revision_type_de_champ
|
||||||
has_one :procedure, through: :revision
|
has_one :procedure, through: :revision
|
||||||
|
|
||||||
delegate :estimated_fill_duration, :estimated_read_duration, :tags_for_template, :libelle_for_export, to: :dynamic_type
|
delegate :estimated_fill_duration, :estimated_read_duration, :tags_for_template, :libelle_for_export, :primary_options, :secondary_options, to: :dynamic_type
|
||||||
delegate :used_by_routing_rules?, to: :revision_type_de_champ
|
delegate :used_by_routing_rules?, to: :revision_type_de_champ
|
||||||
|
|
||||||
class WithIndifferentAccess
|
class WithIndifferentAccess
|
||||||
|
@ -167,8 +167,6 @@ class TypeDeChamp < ApplicationRecord
|
||||||
|
|
||||||
attr_reader :dynamic_type
|
attr_reader :dynamic_type
|
||||||
|
|
||||||
delegate :primary_options, :secondary_options, to: :dynamic_type
|
|
||||||
|
|
||||||
scope :public_only, -> { where(private: false) }
|
scope :public_only, -> { where(private: false) }
|
||||||
scope :private_only, -> { where(private: true) }
|
scope :private_only, -> { where(private: true) }
|
||||||
scope :repetition, -> { where(type_champ: type_champs.fetch(:repetition)) }
|
scope :repetition, -> { where(type_champ: type_champs.fetch(:repetition)) }
|
||||||
|
@ -526,6 +524,17 @@ class TypeDeChamp < ApplicationRecord
|
||||||
previous_section_level(tdcs.take(tdcs.find_index(self)))
|
previous_section_level(tdcs.take(tdcs.find_index(self)))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def level_for_revision(revision)
|
||||||
|
rtdc = revision.revision_types_de_champ.find { |rtdc| rtdc.stable_id == stable_id }
|
||||||
|
if rtdc.child?
|
||||||
|
header_section_level_value.to_i + rtdc.parent.type_de_champ.current_section_level(revision)
|
||||||
|
elsif header_section_level_value
|
||||||
|
header_section_level_value.to_i
|
||||||
|
else
|
||||||
|
0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def self.filter_hash_type(type_champ)
|
def self.filter_hash_type(type_champ)
|
||||||
if is_choice_type_from(type_champ)
|
if is_choice_type_from(type_champ)
|
||||||
:enum
|
:enum
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
- if @row_id.present?
|
- if @row_id.present?
|
||||||
= fields_for @champ.input_name, @champ do |form|
|
= fields_for @champ.input_name, @champ do |form|
|
||||||
= turbo_stream.append dom_id(@champ, :rows), render(EditableChamp::RepetitionRowComponent.new(form: form, champ: @champ, row_id: @row_id))
|
= turbo_stream.append dom_id(@champ, :rows), render(EditableChamp::RepetitionRowComponent.new(form: form, dossier: @champ.dossier, type_de_champ: @champ.type_de_champ, row_id: @row_id, row_number: @row_number))
|
||||||
- if @first_champ_id
|
- if @first_champ_id
|
||||||
= turbo_stream.focus(@first_champ_id)
|
= turbo_stream.focus(@first_champ_id)
|
||||||
|
|
|
@ -15,13 +15,13 @@
|
||||||
|
|
||||||
- types_de_champ_public = @dossier.revision.types_de_champ_public
|
- types_de_champ_public = @dossier.revision.types_de_champ_public
|
||||||
- if types_de_champ_public.any? || @dossier.procedure.routing_enabled?
|
- if types_de_champ_public.any? || @dossier.procedure.routing_enabled?
|
||||||
= render partial: "shared/dossiers/champs", locals: { types_de_champ: types_de_champ_public, dossier: @dossier, demande_seen_at: nil, profile: 'instructeur' }
|
= render ViewableChamp::SectionComponent.new(dossier: @dossier, types_de_champ: types_de_champ_public, demande_seen_at: nil, profile: 'instructeur')
|
||||||
|
|
||||||
%h2 Annotations privées
|
%h2 Annotations privées
|
||||||
|
|
||||||
- types_de_champ_private = @dossier.revision.types_de_champ_private
|
- types_de_champ_private = @dossier.revision.types_de_champ_private
|
||||||
- if types_de_champ_private.any?
|
- if types_de_champ_private.any?
|
||||||
= render partial: "shared/dossiers/champs", locals: { types_de_champ: types_de_champ_private, dossier: @dossier, demande_seen_at: nil, profile: 'instructeur' }
|
= render ViewableChamp::SectionComponent.new(dossier: @dossier, types_de_champ: types_de_champ_private, demande_seen_at: nil, profile: 'instructeur')
|
||||||
- else
|
- else
|
||||||
Aucune annotation privée
|
Aucune annotation privée
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
|
|
||||||
%form.form
|
%form.form
|
||||||
= form_for @dossier, url: '', html: { class: 'form' } do |f|
|
= form_for @dossier, url: '', html: { class: 'form' } do |f|
|
||||||
= render EditableChamp::SectionComponent.new(types_de_champ: @dossier.revision.types_de_champ_public, champs_by_stable_id_with_row: @dossier.champs_by_stable_id_with_row)
|
= render EditableChamp::SectionComponent.new(dossier: @dossier, types_de_champ: @dossier.revision.types_de_champ_public)
|
||||||
|
|
||||||
.editable-champ.editable-champ-text
|
.editable-champ.editable-champ-text
|
||||||
%label Mot de passe
|
%label Mot de passe
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
= render ViewableChamp::SectionComponent.new(types_de_champ:, champs_by_stable_id_with_row: dossier.champs_by_stable_id_with_row, demande_seen_at:, profile:)
|
|
|
@ -53,4 +53,4 @@
|
||||||
|
|
||||||
- types_de_champ = dossier.revision.types_de_champ_public
|
- types_de_champ = dossier.revision.types_de_champ_public
|
||||||
- if types_de_champ.any? || dossier.procedure.routing_enabled?
|
- if types_de_champ.any? || dossier.procedure.routing_enabled?
|
||||||
= render partial: "shared/dossiers/champs", locals: { types_de_champ:, dossier:, demande_seen_at:, profile: }
|
= render ViewableChamp::SectionComponent.new(dossier:, types_de_champ:, demande_seen_at:, profile:)
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
= render Procedure::NoticeComponent.new(procedure: dossier.procedure)
|
= render Procedure::NoticeComponent.new(procedure: dossier.procedure)
|
||||||
|
|
||||||
= render EditableChamp::SectionComponent.new(types_de_champ: dossier_for_editing.revision.types_de_champ_public, champs_by_stable_id_with_row: dossier_for_editing.champs_by_stable_id_with_row)
|
= render EditableChamp::SectionComponent.new(dossier: dossier_for_editing, types_de_champ: dossier_for_editing.revision.types_de_champ_public)
|
||||||
|
|
||||||
= render Dossiers::PendingCorrectionCheckboxComponent.new(dossier: dossier)
|
= render Dossiers::PendingCorrectionCheckboxComponent.new(dossier: dossier)
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
%section.counter-start-header-section
|
%section.counter-start-header-section
|
||||||
= render NestedForms::FormOwnerComponent.new
|
= render NestedForms::FormOwnerComponent.new
|
||||||
= form_for dossier, url: annotations_instructeur_dossier_path(dossier.procedure, dossier), html: { class: 'form', multipart: true } do |f|
|
= form_for dossier, url: annotations_instructeur_dossier_path(dossier.procedure, dossier), html: { class: 'form', multipart: true } do |f|
|
||||||
= render EditableChamp::SectionComponent.new(types_de_champ: dossier.revision.types_de_champ_private, champs_by_stable_id_with_row: dossier.champs_by_stable_id_with_row)
|
= render EditableChamp::SectionComponent.new(dossier:, types_de_champ: dossier.revision.types_de_champ_private)
|
||||||
|
|
||||||
= render Dossiers::EditFooterComponent.new(dossier: dossier, annotation: true)
|
= render Dossiers::EditFooterComponent.new(dossier: dossier, annotation: true)
|
||||||
- else
|
- else
|
||||||
|
|
|
@ -191,10 +191,13 @@ Rails.application.routes.draw do
|
||||||
end
|
end
|
||||||
|
|
||||||
namespace :champs do
|
namespace :champs do
|
||||||
|
post ':dossier_id/:stable_id/repetition', to: 'repetition#add', as: :repetition
|
||||||
|
delete ':dossier_id/:stable_id/repetition', to: 'repetition#remove'
|
||||||
|
post ':champ_id/repetition', to: 'repetition#add'
|
||||||
|
delete ':champ_id/repetition', to: 'repetition#remove'
|
||||||
|
|
||||||
get ':champ_id/siret', to: 'siret#show', as: :siret
|
get ':champ_id/siret', to: 'siret#show', as: :siret
|
||||||
get ':champ_id/rna', to: 'rna#show', as: :rna
|
get ':champ_id/rna', to: 'rna#show', as: :rna
|
||||||
post ':champ_id/repetition', to: 'repetition#add', as: :repetition
|
|
||||||
delete ':champ_id/repetition', to: 'repetition#remove'
|
|
||||||
delete ':champ_id/options', to: 'options#remove', as: :options
|
delete ':champ_id/options', to: 'options#remove', as: :options
|
||||||
|
|
||||||
get ':champ_id/carte/features', to: 'carte#index', as: :carte_features
|
get ':champ_id/carte/features', to: 'carte#index', as: :carte_features
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
describe EditableChamp::SectionComponent, type: :component do
|
describe EditableChamp::SectionComponent, type: :component do
|
||||||
include TreeableConcern
|
include TreeableConcern
|
||||||
let(:types_de_champ) { champs.map(&:type_de_champ) }
|
let(:procedure) { create(:procedure, types_de_champ_public:) }
|
||||||
let(:champs_by_stable_id_with_row) { champs.index_by(&:stable_id_with_row) }
|
let(:types_de_champ_public) { [] }
|
||||||
let(:component) { described_class.new(types_de_champ:, champs_by_stable_id_with_row:) }
|
let(:dossier) { create(:dossier, :with_populated_champs, procedure:) }
|
||||||
|
let(:types_de_champ) { dossier.revision.types_de_champ_public }
|
||||||
|
let(:component) { described_class.new(types_de_champ:, dossier:) }
|
||||||
before { render_inline(component).to_html }
|
before { render_inline(component).to_html }
|
||||||
|
|
||||||
context 'list of champs without an header_section' do
|
context 'list of champs without an header_section' do
|
||||||
let(:champs) { [build(:champ_text), build(:champ_textarea)] }
|
let(:types_de_champ_public) { [{ type: :text }, { type: :textarea }] }
|
||||||
|
|
||||||
it 'render in a fieldset' do
|
it 'render in a fieldset' do
|
||||||
expect(page).to have_selector("fieldset", count: 1)
|
expect(page).to have_selector("fieldset", count: 1)
|
||||||
|
@ -19,7 +21,7 @@ describe EditableChamp::SectionComponent, type: :component do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'list of champs with an header_section' do
|
context 'list of champs with an header_section' do
|
||||||
let(:champs) { [build(:champ_header_section_level_1), build(:champ_text), build(:champ_textarea)] }
|
let(:types_de_champ_public) { [{ type: :header_section, level: 1 }, { type: :text }, { type: :textarea }] }
|
||||||
|
|
||||||
it 'renders fieldset' do
|
it 'renders fieldset' do
|
||||||
expect(page).to have_selector("fieldset")
|
expect(page).to have_selector("fieldset")
|
||||||
|
@ -33,7 +35,7 @@ describe EditableChamp::SectionComponent, type: :component do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'list of champs without section and an header_section having champs' do
|
context 'list of champs without section and an header_section having champs' do
|
||||||
let(:champs) { [build(:champ_text), build(:champ_header_section_level_1), build(:champ_text)] }
|
let(:types_de_champ_public) { [{ type: :text }, { type: :header_section, level: 1 }, { type: :text }] }
|
||||||
|
|
||||||
it 'renders fieldset' do
|
it 'renders fieldset' do
|
||||||
expect(page).to have_selector("fieldset", count: 2)
|
expect(page).to have_selector("fieldset", count: 2)
|
||||||
|
@ -47,7 +49,7 @@ describe EditableChamp::SectionComponent, type: :component do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'list of header_section without champs' do
|
context 'list of header_section without champs' do
|
||||||
let(:champs) { [build(:champ_header_section_level_1), build(:champ_header_section_level_2), build(:champ_header_section_level_3)] }
|
let(:types_de_champ_public) { [{ type: :header_section, level: 1 }, { type: :header_section, level: 2 }, { type: :header_section, level: 3 }] }
|
||||||
|
|
||||||
it 'render header within fieldset' do
|
it 'render header within fieldset' do
|
||||||
expect(page).to have_selector("fieldset > legend", count: 3)
|
expect(page).to have_selector("fieldset > legend", count: 3)
|
||||||
|
@ -58,7 +60,7 @@ describe EditableChamp::SectionComponent, type: :component do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'header_section followed by explication and another fieldset' do
|
context 'header_section followed by explication and another fieldset' do
|
||||||
let(:champs) { [build(:champ_header_section_level_1), build(:champ_explication), build(:champ_header_section_level_1), build(:champ_text)] }
|
let(:types_de_champ_public) { [{ type: :header_section, level: 1 }, { type: :explication }, { type: :header_section, level: 1 }, { type: :text }] }
|
||||||
|
|
||||||
it 'render fieldset, header_section, also render explication' do
|
it 'render fieldset, header_section, also render explication' do
|
||||||
expect(page).to have_selector("h2", count: 2)
|
expect(page).to have_selector("h2", count: 2)
|
||||||
|
@ -69,7 +71,7 @@ describe EditableChamp::SectionComponent, type: :component do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'nested fieldsset' do
|
context 'nested fieldsset' do
|
||||||
let(:champs) { [build(:champ_header_section_level_1), build(:champ_text), build(:champ_header_section_level_2), build(:champ_textarea)] }
|
let(:types_de_champ_public) { [{ type: :header_section, level: 1 }, { type: :text }, { type: :header_section, level: 2 }, { type: :textarea }] }
|
||||||
|
|
||||||
it 'render nested fieldsets' do
|
it 'render nested fieldsets' do
|
||||||
expect(page).to have_selector("fieldset")
|
expect(page).to have_selector("fieldset")
|
||||||
|
@ -85,22 +87,19 @@ describe EditableChamp::SectionComponent, type: :component do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with repetition' do
|
context 'with repetition' do
|
||||||
let(:procedure) do
|
let(:types_de_champ_public) do
|
||||||
create(:procedure, types_de_champ_public: [
|
[
|
||||||
{ type: :header_section, header_section_level: 1 },
|
{ type: :header_section, level: 1 },
|
||||||
{
|
{
|
||||||
type: :repetition,
|
type: :repetition,
|
||||||
libelle: 'repetition',
|
libelle: 'repetition',
|
||||||
children: [
|
children: [
|
||||||
{ type: :header_section, header_section_level: 1, libelle: 'child_1' },
|
{ type: :header_section, level: 1, libelle: 'child_1' },
|
||||||
{ type: :text, libelle: 'child_2' }
|
{ type: :text, libelle: 'child_2' }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
])
|
]
|
||||||
end
|
end
|
||||||
let(:dossier) { create(:dossier, :with_populated_champs, procedure: procedure) }
|
|
||||||
let(:champs) { dossier.champs_public }
|
|
||||||
let(:champs_by_stable_id_with_row) { dossier.champs_by_stable_id_with_row }
|
|
||||||
|
|
||||||
it 'render nested fieldsets, increase heading level for repetition header_section' do
|
it 'render nested fieldsets, increase heading level for repetition header_section' do
|
||||||
expect(page).to have_selector("fieldset")
|
expect(page).to have_selector("fieldset")
|
||||||
|
@ -137,24 +136,24 @@ describe EditableChamp::SectionComponent, type: :component do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:champs) {
|
let(:types_de_champ_public) {
|
||||||
[
|
[
|
||||||
build(:champ_header_section_level_1),
|
{ type: :header_section, level: 1 },
|
||||||
build(:champ_header_section_level_2),
|
{ type: :header_section, level: 2 },
|
||||||
build(:champ_header_section_level_3),
|
{ type: :header_section, level: 3 },
|
||||||
build(:champ_integer_number),
|
{ type: :integer_number },
|
||||||
|
|
||||||
build(:champ_header_section_level_3),
|
{ type: :header_section, level: 3 },
|
||||||
build(:champ_yes_no),
|
{ type: :yes_no },
|
||||||
|
|
||||||
build(:champ_header_section_level_2),
|
{ type: :header_section, level: 2 },
|
||||||
build(:champ_header_section_level_3),
|
{ type: :header_section, level: 3 },
|
||||||
build(:champ_integer_number),
|
{ type: :integer_number },
|
||||||
|
|
||||||
build(:champ_header_section_level_1),
|
{ type: :header_section, level: 1 },
|
||||||
build(:champ_text),
|
{ type: :text },
|
||||||
build(:champ_header_section_level_2),
|
{ type: :header_section, level: 2 },
|
||||||
build(:champ_text)
|
{ type: :text }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -319,6 +319,10 @@ def build_types_de_champ(types_de_champ, revision:, scope: :public, parent: nil)
|
||||||
type_de_champ_attributes[:editable_options] = layers.index_with { '1' }
|
type_de_champ_attributes[:editable_options] = layers.index_with { '1' }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if type == :header_section
|
||||||
|
type_de_champ_attributes[:header_section_level] = type_de_champ_attributes.delete(:level)
|
||||||
|
end
|
||||||
|
|
||||||
type_de_champ = if scope == :private
|
type_de_champ = if scope == :private
|
||||||
build(:"type_de_champ_#{type}", :private, no_coordinate: true, **type_de_champ_attributes)
|
build(:"type_de_champ_#{type}", :private, no_coordinate: true, **type_de_champ_attributes)
|
||||||
else
|
else
|
||||||
|
|
|
@ -46,18 +46,6 @@ describe Dossier, type: :model do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'with_champs' do
|
|
||||||
let(:procedure) { create(:procedure) }
|
|
||||||
let!(:tdc_1) { create(:type_de_champ, libelle: 'l1', position: 1, procedure: procedure) }
|
|
||||||
let!(:tdc_3) { create(:type_de_champ, libelle: 'l3', position: 3, procedure: procedure) }
|
|
||||||
let!(:tdc_2) { create(:type_de_champ, libelle: 'l2', position: 2, procedure: procedure) }
|
|
||||||
let(:dossier) { create(:dossier, procedure: procedure) }
|
|
||||||
|
|
||||||
it do
|
|
||||||
expect(Dossier.with_champs.find(dossier.id).champs_public.map(&:libelle)).to match(['l1', 'l2', 'l3'])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe 'brouillon_close_to_expiration' do
|
describe 'brouillon_close_to_expiration' do
|
||||||
let(:procedure) { create(:procedure, :published, duree_conservation_dossiers_dans_ds: 6) }
|
let(:procedure) { create(:procedure, :published, duree_conservation_dossiers_dans_ds: 6) }
|
||||||
let!(:young_dossier) { create(:dossier, :en_construction, procedure: procedure) }
|
let!(:young_dossier) { create(:dossier, :en_construction, procedure: procedure) }
|
||||||
|
|
|
@ -15,7 +15,7 @@ describe 'shared/dossiers/champs', type: :view do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
subject { render 'shared/dossiers/champs', types_de_champ:, dossier:, demande_seen_at:, profile: }
|
subject { render ViewableChamp::SectionComponent.new(types_de_champ:, dossier:, demande_seen_at:, profile:) }
|
||||||
|
|
||||||
context "there are some champs" do
|
context "there are some champs" do
|
||||||
let(:types_de_champ_public) { [{ type: :checkbox }, { type: :header_section }, { type: :explication }, { type: :dossier_link }, { type: :textarea }, { type: :rna }] }
|
let(:types_de_champ_public) { [{ type: :checkbox }, { type: :header_section }, { type: :explication }, { type: :dossier_link }, { type: :textarea }, { type: :rna }] }
|
||||||
|
|
Loading…
Reference in a new issue