Skip to content

Commit

Permalink
Merge pull request #11113 from demarches-simplifiees/fix-11103
Browse files Browse the repository at this point in the history
ETQ instructeur, je peux inclure les dossiers "archivés" quand je télécharge les dossiers de l'onglet "Au total"
  • Loading branch information
colinux authored Dec 20, 2024
2 parents 950e3ba + 022cd6c commit 04ad666
Show file tree
Hide file tree
Showing 13 changed files with 113 additions and 16 deletions.
15 changes: 14 additions & 1 deletion app/components/dossiers/export_dropdown_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ class Dossiers::ExportDropdownComponent < ApplicationComponent
attr_reader :wrapper
attr_reader :export_templates

def initialize(procedure:, export_templates: nil, statut: nil, count: nil, class_btn: nil, export_url: nil, show_export_template_tab: true, wrapper: :div)
def initialize(procedure:, export_templates: nil, statut: nil, count: nil, archived_count: 0, class_btn: nil, export_url: nil, show_export_template_tab: true, wrapper: :div)
@procedure = procedure
@export_templates = export_templates
@statut = statut
@count = count
@archived_count = archived_count
@class_btn = class_btn
@export_url = export_url
@show_export_template_tab = show_export_template_tab
Expand All @@ -29,6 +30,18 @@ def allowed_format?(item)
item.fetch(:format) != :json || @procedure.active_revision.carte?
end

def can_include_archived?
@statut == 'tous' && @archived_count > 0
end

def include_archived_title
if @archived_count > 1
"<span>Inclure les <strong>#{@archived_count} dossiers « archivés »</strong></span>"
else
"<span>Inclure le <strong>dossier « archivé »</strong></span>"
end
end

def download_export_path(export_format: nil, export_template_id: nil, no_progress_notification: nil)
@export_url.call(@procedure,
export_format:,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,19 @@

.fr-tabs__panel.fr-pb-8w.fr-tabs__panel--selected{ id: "tabpanel-standard#{@count}-panel", role: "tabpanel", "aria-labelledby": "tabpanel-standard#{@count}", tabindex: "0" }
= form_with url: download_export_path, namespace: "export#{@count}", data: { turbo_method: :post, turbo: true } do |f|

- if can_include_archived?
.fr-pb-2w
= render Dsfr::ToggleComponent.new(form: f,
target: :include_archived,
html_title: include_archived_title)

= f.hidden_field :statut, value: @statut
%fieldset.fr-fieldset#radio-hint{ "aria-labelledby": "radio-hint-legend" }
%legend.fr-fieldset__legend--regular.fr-fieldset__legend#radio-hint-legend Sélectionner le format de l'export
.fr-fieldset__element
.fr-radio-group
= f.radio_button :export_format, 'xlsx'
= f.radio_button :export_format, 'xlsx', checked: true
= f.label :export_format_xlsx, 'Fichier xlsx'
.fr-fieldset__element
.fr-radio-group
Expand Down Expand Up @@ -57,6 +64,12 @@
.fr-tabs__panel.fr-pr-3w.fr-pb-8w{ id: "tabpanel-template#{@count}-panel", role: "tabpanel", "aria-labelledby": "tabpanel-template", tabindex: "0" }
= form_with url: download_export_path, namespace: "export_template_#{@count}", data: { turbo_method: :post, turbo: true } do |f|
= f.hidden_field :statut, value: @statut
- if can_include_archived?
.fr-pb-2w
= render Dsfr::ToggleComponent.new(form: f,
target: :include_archived,
html_title: include_archived_title)

.fr-select-group
- if export_templates.present?
%label.fr-label{ for: 'select' }
Expand Down
18 changes: 16 additions & 2 deletions app/components/dsfr/toggle_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,18 @@
class Dsfr::ToggleComponent < ApplicationComponent
attr_reader :target
attr_reader :title
attr_reader :html_title
attr_reader :hint
attr_reader :toggle_labels
attr_reader :disabled
attr_reader :data
attr_reader :extra_class_names

def initialize(form:, target:, title:, disabled: nil, hint: nil, toggle_labels: { checked: 'Activé', unchecked: 'Désactivé' }, opt: nil, extra_class_names: nil)
def initialize(form:, target:, title: nil, html_title: nil, disabled: nil, hint: nil, toggle_labels: { checked: 'Activé', unchecked: 'Désactivé' }, opt: nil, extra_class_names: nil)
@form = form
@target = target
@title = title
@html_title = html_title
@hint = hint
@disabled = disabled
@toggle_labels = toggle_labels
Expand All @@ -22,7 +24,19 @@ def initialize(form:, target:, title:, disabled: nil, hint: nil, toggle_labels:

private

def label_for
return input_id if @form.object.present?

return "#{@form.options[:namespace]}_#{target}" if @form.options[:namespace].present?

target.to_s
end

def input_id
dom_id(@form.object, target)
if @form.object.present?
dom_id(@form.object, target)
else
target.to_s
end
end
end
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
%div{ class: "fr-toggle fr-toggle--label-left #{extra_class_names}" }
= @form.check_box target, class: 'fr-toggle__input', disabled:, data:, id: input_id
= @form.label target,
title,
for: input_id,
title || html_title&.html_safe,
for: label_for,
data: { 'fr-checked-label': toggle_labels[:checked], 'fr-unchecked-label': toggle_labels[:unchecked] },
class: 'fr-toggle__label'

Expand Down
7 changes: 7 additions & 0 deletions app/controllers/instructeurs/procedures_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,12 @@ def show
page = params[:page].presence || 1

@dossiers_count = @filtered_sorted_ids.size
@archived_dossiers_count = if statut == 'tous'
@counts[:archives]
else
0
end

@filtered_sorted_paginated_ids = Kaminari
.paginate_array(@filtered_sorted_ids)
.page(page)
Expand Down Expand Up @@ -317,6 +323,7 @@ def export_options
time_span_type: params[:time_span_type],
statut: params[:statut],
export_template:,
include_archived: params[:include_archived],
procedure_presentation: params[:statut].present? ? procedure_presentation : nil
}.compact
end
Expand Down
6 changes: 3 additions & 3 deletions app/models/dossier.rb
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ def classer_sans_suite(motivation: nil, instructeur: nil, processed_at: Time.zon

scope :with_type_de_champ, -> (stable_id) { joins(:champs).where(champs: { stream: 'main', stable_id: }) }

scope :all_state, -> { not_archived.state_not_brouillon }
scope :all_state, -> (include_archived: false) { include_archived ? state_not_brouillon : not_archived.state_not_brouillon }
scope :en_construction, -> { not_archived.state_en_construction }
scope :en_instruction, -> { not_archived.state_en_instruction }
scope :termine, -> { not_archived.state_termine }
Expand Down Expand Up @@ -385,7 +385,7 @@ def classer_sans_suite(motivation: nil, instructeur: nil, processed_at: Time.zon
.distinct
end

scope :by_statut, -> (statut, instructeur = nil) do
scope :by_statut, -> (statut, instructeur: nil, include_archived: false) do
case statut
when 'a-suivre'
visible_by_administration
Expand All @@ -399,7 +399,7 @@ def classer_sans_suite(motivation: nil, instructeur: nil, processed_at: Time.zon
when 'traites'
visible_by_administration.termine
when 'tous'
visible_by_administration.all_state
visible_by_administration.all_state(include_archived:)
when 'supprimes'
hidden_by_administration.state_termine.or(hidden_by_expired)
when 'archives'
Expand Down
5 changes: 3 additions & 2 deletions app/models/export.rb
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def since
time_span_type == Export.time_span_types.fetch(:monthly) ? 30.days.ago : nil
end

def self.find_or_create_fresh_export(format, groupe_instructeurs, user_profile, time_span_type: time_span_types.fetch(:everything), statut: statuts.fetch(:tous), procedure_presentation: nil, export_template: nil)
def self.find_or_create_fresh_export(format, groupe_instructeurs, user_profile, time_span_type: time_span_types.fetch(:everything), statut: statuts.fetch(:tous), procedure_presentation: nil, export_template: nil, include_archived: false)
filtered_columns = Array.wrap(procedure_presentation&.filters_for(statut))
sorted_column = procedure_presentation&.sorted_column

Expand All @@ -78,6 +78,7 @@ def self.find_or_create_fresh_export(format, groupe_instructeurs, user_profile,
export_template:,
time_span_type:,
statut:,
include_archived:,
key: generate_cache_key(groupe_instructeurs.map(&:id), filtered_columns, sorted_column)
}

Expand Down Expand Up @@ -136,7 +137,7 @@ def dossiers_for_export
dossiers.visible_by_administration.where('dossiers.depose_at > ?', since)
elsif filtered_columns.present? || sorted_column.present?
instructeur = instructeur_from(user_profile)
filtered_sorted_ids = DossierFilterService.filtered_sorted_ids(dossiers, statut, filtered_columns, sorted_column, instructeur)
filtered_sorted_ids = DossierFilterService.filtered_sorted_ids(dossiers, statut, filtered_columns, sorted_column, instructeur, include_archived: include_archived)

dossiers.where(id: filtered_sorted_ids)
else
Expand Down
4 changes: 2 additions & 2 deletions app/services/dossier_filter_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
class DossierFilterService
TYPE_DE_CHAMP = 'type_de_champ'

def self.filtered_sorted_ids(dossiers, statut, filters, sorted_column, instructeur, count: nil)
dossiers_by_statut = dossiers.by_statut(statut, instructeur)
def self.filtered_sorted_ids(dossiers, statut, filters, sorted_column, instructeur, count: nil, include_archived: false)
dossiers_by_statut = dossiers.by_statut(statut, instructeur:, include_archived:)
dossiers_sorted_ids = self.sorted_ids(dossiers_by_statut, sorted_column, instructeur, count || dossiers_by_statut.size)

if filters.present?
Expand Down
2 changes: 1 addition & 1 deletion app/views/instructeurs/procedures/show.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
.fr-ml-auto
- if @dossiers_count > 0
%ul.fr-btns-group.fr-btns-group--right.fr-btns-group--sm.fr-btns-group--inline-md.fr-btns-group--icon-left
= render Dossiers::ExportDropdownComponent.new(wrapper: :li, procedure: @procedure, export_templates: current_instructeur.export_templates_for(@procedure), statut: @statut, count: @dossiers_count,
= render Dossiers::ExportDropdownComponent.new(wrapper: :li, procedure: @procedure, export_templates: current_instructeur.export_templates_for(@procedure), statut: @statut, count: @dossiers_count, archived_count: @archived_dossiers_count,
class_btn: 'fr-btn--secondary fr-icon-download-line', export_url: method(:download_export_instructeur_procedure_path))

= render Dropdown::MenuComponent.new(wrapper: :li, button_options: { class: ['fr-btn--tertiary', 'fr-icon-settings-5-line'] }, menu_options: { id: 'custom-menu' }) do |menu|
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

class AddIncludeArchivedDossiersInExport < ActiveRecord::Migration[7.0]
def change
add_column :exports, :include_archived, :boolean, default: false, null: false
end
end
3 changes: 2 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[7.0].define(version: 2024_11_26_145420) do
ActiveRecord::Schema[7.0].define(version: 2024_12_03_154714) do
# These are extensions that must be enabled in order to support this database
enable_extension "pg_buffercache"
enable_extension "pg_stat_statements"
Expand Down Expand Up @@ -643,6 +643,7 @@
t.bigint "export_template_id"
t.jsonb "filtered_columns", default: [], null: false, array: true
t.string "format", null: false
t.boolean "include_archived", default: false, null: false
t.bigint "instructeur_id"
t.string "job_status", default: "pending", null: false
t.text "key", null: false
Expand Down
31 changes: 31 additions & 0 deletions spec/components/dossiers/export_dropdown_component_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# frozen_string_literal: true

require 'rails_helper'

RSpec.describe Dossiers::ExportDropdownComponent, type: :component do
subject(:component) { described_class.new(**params) }

describe '#include_archived_title' do
let(:procedure) { double('Procedure') }

context 'when archived_count is greater than 1' do
it 'returns the pluralized archived title' do
component = Dossiers::ExportDropdownComponent.new(
procedure: procedure,
archived_count: 3
)
expect(component.include_archived_title).to eq("<span>Inclure les <strong>3 dossiers « archivés »</strong></span>")
end
end

context 'when archived_count is 1 or less' do
it 'returns the singular archived title' do
component = Dossiers::ExportDropdownComponent.new(
procedure: procedure,
archived_count: 1
)
expect(component.include_archived_title).to eq("<span>Inclure le <strong>dossier « archivé »</strong></span>")
end
end
end
end
12 changes: 11 additions & 1 deletion spec/services/dossier_filter_service_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,30 @@ def to_filter((label, filter)) = FilteredColumn.new(column: procedure.find_colum
let(:dossiers) { procedure.dossiers }
let(:statut) { 'suivis' }
let(:filters) { [] }
let(:include_archived) { false }
let(:sorted_columns) { procedure.default_sorted_column }

subject { described_class.filtered_sorted_ids(dossiers, statut, filters, sorted_columns, instructeur) }
subject { described_class.filtered_sorted_ids(dossiers, statut, filters, sorted_columns, instructeur, include_archived:) }

context 'with no filters' do
let(:en_construction_dossier) { create(:dossier, :en_construction, procedure:) }
let(:accepte_dossier) { create(:dossier, :accepte, procedure:) }
let(:archived_dossier) { create(:dossier, :accepte, :archived, procedure:) }

before do
create(:follow, dossier: en_construction_dossier, instructeur:)
create(:follow, dossier: accepte_dossier, instructeur:)
create(:follow, dossier: archived_dossier, instructeur:)
end

it { is_expected.to contain_exactly(en_construction_dossier.id) }

context 'when include_archived is true' do
let(:include_archived) { true }
let(:statut) { 'tous' }

it { is_expected.to contain_exactly(en_construction_dossier.id, accepte_dossier.id, archived_dossier.id) }
end
end

context 'with mocked sorted_ids' do
Expand Down

0 comments on commit 04ad666

Please sign in to comment.