diff --git a/app/components/dossiers/champs_rows_show_component/champs_rows_show_component.html.haml b/app/components/dossiers/champs_rows_show_component/champs_rows_show_component.html.haml index fb07850b8..11382ad4a 100644 --- a/app/components/dossiers/champs_rows_show_component/champs_rows_show_component.html.haml +++ b/app/components/dossiers/champs_rows_show_component/champs_rows_show_component.html.haml @@ -1,10 +1,9 @@ - each_champ do |champ| - if champ.repetition? - - champ.rows.each.with_index do |row, i| - .fr-background-alt--grey.fr-p-2w.fr-my-3w.fr-ml-2w.champ-repetition - %p.font-weight-bold= "#{champ.libelle} #{i + 1} :" - - = render Dossiers::ChampsRowsShowComponent.new(champs: row, seen_at:, profile:) + - 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 do |row_id| + = render ViewableChamp::SectionComponent.new(types_de_champ:, champs_by_stable_id_with_row:, row_id:, demande_seen_at: seen_at, profile:) - 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| diff --git a/app/components/editable_champ/repetition_component/repetition_component.html.haml b/app/components/editable_champ/repetition_component/repetition_component.html.haml index 6e0f83525..e2b565d89 100644 --- a/app/components/editable_champ/repetition_component/repetition_component.html.haml +++ b/app/components/editable_champ/repetition_component/repetition_component.html.haml @@ -5,8 +5,8 @@ .repetition{ id: dom_id(@champ, :rows) } - - @champ.rows.each do |champs| - = render EditableChamp::RepetitionRowComponent.new(form: @form, champ: @champ, row: champs, seen_at: @seen_at) + - @champ.row_ids.each do |row_id| + = render EditableChamp::RepetitionRowComponent.new(form: @form, champ: @champ, row_id:, seen_at: @seen_at) .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 diff --git a/app/components/editable_champ/repetition_row_component.rb b/app/components/editable_champ/repetition_row_component.rb index e647b5640..207d1a241 100644 --- a/app/components/editable_champ/repetition_row_component.rb +++ b/app/components/editable_champ/repetition_row_component.rb @@ -1,5 +1,17 @@ class EditableChamp::RepetitionRowComponent < ApplicationComponent - def initialize(form:, champ:, row:, seen_at: nil) - @form, @champ, @row, @seen_at = form, champ, row, seen_at + def initialize(form:, champ:, row_id:, seen_at: nil) + @form, @champ, @row_id, @seen_at = form, champ, row_id, seen_at + + @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 + + attr_reader :row_id, :row_number + + private + + 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:) end end diff --git a/app/components/editable_champ/repetition_row_component/repetition_row_component.html.haml b/app/components/editable_champ/repetition_row_component/repetition_row_component.html.haml index 8b49d0f99..df3dc005b 100644 --- a/app/components/editable_champ/repetition_row_component/repetition_row_component.html.haml +++ b/app/components/editable_champ/repetition_row_component/repetition_row_component.html.haml @@ -1,12 +1,11 @@ -- row_id = "safe-row-selector-#{@row.first.row_id}" -.row{ id: row_id } - - if @row.size > 1 +.row{ id: "safe-row-selector-#{row_id}" } + - if @types_de_champ.size > 1 %fieldset %legend.block-id= "#{@champ.libelle} " - = render EditableChamp::SectionComponent.new(champs: @row) + = render section_component - else - = render EditableChamp::SectionComponent.new(champs: @row) + = render section_component .flex.row-reverse - = render NestedForms::OwnedButtonComponent.new(formaction: champs_repetition_path(@champ.id, row_id: @row.first.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: @champ.rows.find_index(@row))}) do + = 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 = t(".delete") diff --git a/app/components/editable_champ/section_component.rb b/app/components/editable_champ/section_component.rb index 55007bc66..6a00123cd 100644 --- a/app/components/editable_champ/section_component.rb +++ b/app/components/editable_champ/section_component.rb @@ -2,8 +2,10 @@ class EditableChamp::SectionComponent < ApplicationComponent include ApplicationHelper include TreeableConcern - def initialize(nodes: nil, champs: nil) - nodes ||= to_tree(champs:) + def initialize(nodes: nil, types_de_champ: nil, row_id: nil, champs_by_stable_id_with_row:) + nodes ||= to_tree(types_de_champ:) + @champs_by_stable_id_with_row = champs_by_stable_id_with_row + @row_id = row_id @nodes = to_fieldset(nodes:) end @@ -12,7 +14,8 @@ class EditableChamp::SectionComponent < ApplicationComponent end def header_section - @nodes.first if @nodes.first.is_a?(Champs::HeaderSectionChamp) + node = @nodes.first + champ_for_type_de_champ(node) if node.is_a?(TypeDeChamp) && node.header_section? end def splitted_tail @@ -35,17 +38,21 @@ class EditableChamp::SectionComponent < ApplicationComponent when EditableChamp::SectionComponent [node, nil] else - [nil, node] + [nil, champ_for_type_de_champ(node)] end end private def to_fieldset(nodes:) - nodes.map { _1.is_a?(Array) ? EditableChamp::SectionComponent.new(nodes: _1) : _1 } + 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 } end def first_champ_is_an_header_section? header_section.present? 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 diff --git a/app/components/viewable_champ/section_component.rb b/app/components/viewable_champ/section_component.rb index 6debfb874..b3024f318 100644 --- a/app/components/viewable_champ/section_component.rb +++ b/app/components/viewable_champ/section_component.rb @@ -2,9 +2,9 @@ class ViewableChamp::SectionComponent < ApplicationComponent include ApplicationHelper include TreeableConcern - def initialize(champs: nil, nodes: nil, demande_seen_at:, profile:) - @demande_seen_at, @profile, @repetition = demande_seen_at, profile - nodes ||= to_tree(champs:) + def initialize(nodes: nil, types_de_champ: nil, row_id: nil, demande_seen_at:, profile:, champs_by_stable_id_with_row:) + @demande_seen_at, @profile, @row_id, @champs_by_stable_id_with_row = demande_seen_at, profile, row_id, champs_by_stable_id_with_row + nodes ||= to_tree(types_de_champ:) @nodes = to_sections(nodes:) end @@ -13,17 +13,18 @@ class ViewableChamp::SectionComponent < ApplicationComponent end def header_section - if @nodes.first.is_a?(Champs::HeaderSectionChamp) - @nodes.first + maybe_header_section = @nodes.first + if maybe_header_section.is_a?(TypeDeChamp) && maybe_header_section.header_section? + champ_for_type_de_champ(maybe_header_section) end end def champs - tail.filter { _1.is_a?(Champ) } + tail.filter_map { _1.is_a?(TypeDeChamp) ? champ_for_type_de_champ(_1) : nil } end def sections - tail.filter { !_1.is_a?(Champ) } + tail.filter { _1.is_a?(ViewableChamp::SectionComponent) } end def tail @@ -48,6 +49,10 @@ class ViewableChamp::SectionComponent < ApplicationComponent private def to_sections(nodes:) - nodes.map { _1.is_a?(Array) ? ViewableChamp::SectionComponent.new(nodes: _1, demande_seen_at: @demande_seen_at, profile: @profile) : _1 } + 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) : _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 diff --git a/app/models/concerns/treeable_concern.rb b/app/models/concerns/treeable_concern.rb index 81592eff7..174a54304 100644 --- a/app/models/concerns/treeable_concern.rb +++ b/app/models/concerns/treeable_concern.rb @@ -5,30 +5,30 @@ module TreeableConcern # but a repetition can be nested an header_section, so 3+3=6=MAX_DEPTH included do - # as we progress in the list of ordered champs + # as we progress in the list of ordered types_de_champ # we keep a reference to each level of nesting (walk) # when we encounter an header_section, it depends of its own depth of nesting minus 1, ie: # h1 belongs to prior (rooted_tree) # h2 belongs to prior h1 # h3 belongs to prior h2 # h1 belongs to prior (rooted_tree) - # then, each and every champs which are not an header_section + # then, each and every types_de_champ which are not an header_section # are added to the current_tree # given a root_depth at 0, we build a full tree # given a root_depth > 0, we build a partial tree (aka, a repetition) - def to_tree(champs:) + def to_tree(types_de_champ:) rooted_tree = [] walk = Array.new(MAX_DEPTH) walk[0] = rooted_tree current_tree = rooted_tree - champs.each do |champ| - if champ.header_section? - new_tree = [champ] - walk[champ.header_section_level_value - 1].push(new_tree) - current_tree = walk[champ.header_section_level_value] = new_tree + types_de_champ.each do |type_de_champ| + if type_de_champ.header_section? + new_tree = [type_de_champ] + walk[type_de_champ.header_section_level_value - 1].push(new_tree) + current_tree = walk[type_de_champ.header_section_level_value] = new_tree else - current_tree.push(champ) + current_tree.push(type_de_champ) end end rooted_tree