From ba6c5b4db784e3b6af59669fc86ce5eb07358535 Mon Sep 17 00:00:00 2001 From: Martin Date: Mon, 12 Sep 2022 16:30:29 +0200 Subject: [PATCH] feat(instructeur/procedure#index): enhance filter to support processed_at and state [plus en_instruction_at/since] feat(filter): enable filter on dossiers.state, dossiers.processed_at(since), dossiers.en_instruction_at(since) --- app/assets/stylesheets/buttons.scss | 6 ++ app/components/dossiers/filter_component.rb | 23 +++++ .../filter_component/filter_component.en.yml | 5 + .../filter_component/filter_component.fr.yml | 5 + .../filter_component.html.haml | 13 +++ .../instructeurs/procedures_controller.rb | 14 ++- .../controllers/dossier_filter_controller.ts | 13 +++ .../concerns/dossier_filtering_concern.rb | 13 ++- app/models/procedure_presentation.rb | 94 +++++++++++++------ .../procedures/_dossiers_filter.html.haml | 10 +- .../procedures/add_filter.turbo_stream.haml | 2 + config/i18n-tasks.yml | 1 + config/locales/en.yml | 3 - config/locales/fr.yml | 3 - .../models/procedure_presentation/en.yml | 11 ++- .../models/procedure_presentation/fr.yml | 11 ++- config/locales/views/instructeurs/en.yml | 20 ++++ config/locales/views/instructeurs/fr.yml | 8 +- spec/models/procedure_presentation_spec.rb | 56 ++++++----- .../instructeurs/procedure_filters_spec.rb | 19 +++- 20 files changed, 242 insertions(+), 88 deletions(-) create mode 100644 app/components/dossiers/filter_component.rb create mode 100644 app/components/dossiers/filter_component/filter_component.en.yml create mode 100644 app/components/dossiers/filter_component/filter_component.fr.yml create mode 100644 app/components/dossiers/filter_component/filter_component.html.haml create mode 100644 app/javascript/controllers/dossier_filter_controller.ts create mode 100644 app/views/instructeurs/procedures/add_filter.turbo_stream.haml diff --git a/app/assets/stylesheets/buttons.scss b/app/assets/stylesheets/buttons.scss index 07603b370..cd1aee3e0 100644 --- a/app/assets/stylesheets/buttons.scss +++ b/app/assets/stylesheets/buttons.scss @@ -304,6 +304,12 @@ select { width: 200px; display: inline-block; + background-color: $light-grey; + border: 1px solid $border-grey; + } + + [disabled] { + display: none; } } diff --git a/app/components/dossiers/filter_component.rb b/app/components/dossiers/filter_component.rb new file mode 100644 index 000000000..f827393fc --- /dev/null +++ b/app/components/dossiers/filter_component.rb @@ -0,0 +1,23 @@ +class Dossiers::FilterComponent < ApplicationComponent + def initialize(procedure:, procedure_presentation:, statut:, field_id: nil) + @procedure = procedure + @procedure_presentation = procedure_presentation + @statut = statut + @field_id = field_id + end + + attr_reader :procedure, :procedure_presentation, :statut, :field_id + + def filterable_fields_for_select + procedure_presentation.filterable_fields_options + end + + def field_type + return :text if field_id.nil? + procedure_presentation.field_type(field_id) + end + + def options_for_select_of_field + I18n.t(procedure_presentation.field_enum(field_id)).map(&:to_a).map(&:reverse) + end +end diff --git a/app/components/dossiers/filter_component/filter_component.en.yml b/app/components/dossiers/filter_component/filter_component.en.yml new file mode 100644 index 000000000..9287f3f18 --- /dev/null +++ b/app/components/dossiers/filter_component/filter_component.en.yml @@ -0,0 +1,5 @@ +en: + column: Column + value: Value + add_filter: Add filter + diff --git a/app/components/dossiers/filter_component/filter_component.fr.yml b/app/components/dossiers/filter_component/filter_component.fr.yml new file mode 100644 index 000000000..7dcb08f60 --- /dev/null +++ b/app/components/dossiers/filter_component/filter_component.fr.yml @@ -0,0 +1,5 @@ +fr: + column: Colonne + value: Valeur + add_filter: Ajouter le filtre + diff --git a/app/components/dossiers/filter_component/filter_component.html.haml b/app/components/dossiers/filter_component/filter_component.html.haml new file mode 100644 index 000000000..a558a283b --- /dev/null +++ b/app/components/dossiers/filter_component/filter_component.html.haml @@ -0,0 +1,13 @@ += form_tag add_filter_instructeur_procedure_url(procedure), method: :post, class: 'dropdown-form large', id: 'filter-component', data: { controller: 'dossier-filter' } do + = label_tag :field, t('.column') + = select_tag :field, options_for_select(filterable_fields_for_select, field_id), include_blank: field_id.nil?, data: {action: "dossier-filter#onChange"} + %br + = label_tag :value, t('.value'), for: 'value' + - if field_type == :enum + = select_tag :value, options_for_select(options_for_select_of_field), id: 'value', name: 'value' + - else + %input#value{ type: field_type, name: :value, maxlength: ProcedurePresentation::FILTERS_VALUE_MAX_LENGTH, disabled: field_id.nil? ? true : false } + + = hidden_field_tag :statut, statut + %br + = submit_tag t('.add_filter'), class: 'button' diff --git a/app/controllers/instructeurs/procedures_controller.rb b/app/controllers/instructeurs/procedures_controller.rb index 8f26f35ff..121db3010 100644 --- a/app/controllers/instructeurs/procedures_controller.rb +++ b/app/controllers/instructeurs/procedures_controller.rb @@ -127,9 +127,19 @@ module Instructeurs end def add_filter - procedure_presentation.add_filter(statut, params[:field], params[:value]) + respond_to do |format| + format.html do + procedure_presentation.add_filter(statut, params[:field], params[:value]) - redirect_back(fallback_location: instructeur_procedure_url(procedure)) + redirect_back(fallback_location: instructeur_procedure_url(procedure)) + end + format.turbo_stream do + @statut = statut + @procedure = procedure + @procedure_presentation = procedure_presentation + @field = params[:field] + end + end end def remove_filter diff --git a/app/javascript/controllers/dossier_filter_controller.ts b/app/javascript/controllers/dossier_filter_controller.ts new file mode 100644 index 000000000..11b8b4113 --- /dev/null +++ b/app/javascript/controllers/dossier_filter_controller.ts @@ -0,0 +1,13 @@ +import { httpRequest } from '@utils'; +import { ApplicationController } from './application_controller'; + +export class DossierFilterController extends ApplicationController { + onChange() { + const element = this.element as HTMLFormElement; + + httpRequest(element.action, { + method: element.getAttribute('method') ?? '', + body: new FormData(element) + }).turbo(); + } +} diff --git a/app/models/concerns/dossier_filtering_concern.rb b/app/models/concerns/dossier_filtering_concern.rb index c4bc53c18..a35bc6d22 100644 --- a/app/models/concerns/dossier_filtering_concern.rb +++ b/app/models/concerns/dossier_filtering_concern.rb @@ -2,13 +2,18 @@ module DossierFilteringConcern extend ActiveSupport::Concern included do + DATE_SINCE_MAPPING = { + 'updated_since' => 'updated_at', + 'depose_since' => 'depose_at', + 'en_construction_since' => 'en_construction_at', + 'en_instruction_since' => 'en_instruction_at', + 'processed_since' => 'processed_at' + } scope :filter_by_datetimes, lambda { |column, dates| if dates.present? case column - when 'depose_since' - where('dossiers.depose_at >= ?', dates.sort.first) - when 'updated_since' - where('dossiers.updated_at >= ?', dates.sort.first) + when *DATE_SINCE_MAPPING.keys + where("dossiers.#{DATE_SINCE_MAPPING.fetch(column)} >= ?", dates.sort.first) else dates .map { |date| self.where(column => date..(date + 1.day)) } diff --git a/app/models/procedure_presentation.rb b/app/models/procedure_presentation.rb index 9a432958e..ab4143279 100644 --- a/app/models/procedure_presentation.rb +++ b/app/models/procedure_presentation.rb @@ -35,47 +35,60 @@ class ProcedurePresentation < ApplicationRecord validate :check_allowed_filter_columns validate :check_filters_max_length - def fields - fields = [ - field_hash('self', 'created_at'), - field_hash('self', 'en_construction_at'), - field_hash('self', 'depose_at'), - field_hash('self', 'updated_at'), - field_hash('self', 'depose_since', virtual: true), - field_hash('self', 'updated_since', virtual: true), - field_hash('user', 'email'), - field_hash('followers_instructeurs', 'email'), - field_hash('groupe_instructeur', 'label') + def self_fields + [ + field_hash('self', 'created_at', type: :date), + field_hash('self', 'updated_at', type: :date), + field_hash('self', 'depose_at', type: :date), + field_hash('self', 'en_construction_at', type: :date), + field_hash('self', 'en_instruction_at', type: :date), + field_hash('self', 'processed_at', type: :date), + field_hash('self', 'updated_since', type: :date, virtual: true), + field_hash('self', 'depose_since', type: :date, virtual: true), + field_hash('self', 'en_construction_since', type: :date, virtual: true), + field_hash('self', 'en_instruction_since', type: :date, virtual: true), + field_hash('self', 'processed_since', type: :date, virtual: true), + field_hash('self', 'state', type: :enum, scope: 'instructeurs.dossiers.filterable_state') ] + end + + def fields + fields = self_fields + + fields.push( + field_hash('user', 'email', type: :text), + field_hash('followers_instructeurs', 'email', type: :text), + field_hash('groupe_instructeur', 'label', type: :text) + ) if procedure.for_individual fields.push( - field_hash("individual", "prenom"), - field_hash("individual", "nom"), - field_hash("individual", "gender") + field_hash("individual", "prenom", type: :text), + field_hash("individual", "nom", type: :text), + field_hash("individual", "gender", type: :text) ) end if !procedure.for_individual fields.push( - field_hash('etablissement', 'entreprise_siren'), - field_hash('etablissement', 'entreprise_forme_juridique'), - field_hash('etablissement', 'entreprise_nom_commercial'), - field_hash('etablissement', 'entreprise_raison_sociale'), - field_hash('etablissement', 'entreprise_siret_siege_social'), - field_hash('etablissement', 'entreprise_date_creation') + field_hash('etablissement', 'entreprise_siren', type: :text), + field_hash('etablissement', 'entreprise_forme_juridique', type: :text), + field_hash('etablissement', 'entreprise_nom_commercial', type: :text), + field_hash('etablissement', 'entreprise_raison_sociale', type: :text), + field_hash('etablissement', 'entreprise_siret_siege_social', type: :text), + field_hash('etablissement', 'entreprise_date_creation', type: :date) ) fields.push( - field_hash('etablissement', 'siret'), - field_hash('etablissement', 'libelle_naf'), - field_hash('etablissement', 'code_postal') + field_hash('etablissement', 'siret', type: :text), + field_hash('etablissement', 'libelle_naf', type: :text), + field_hash('etablissement', 'code_postal', type: :text) ) end fields.concat procedure.types_de_champ_for_procedure_presentation .pluck(:libelle, :private, :stable_id) - .map { |(libelle, is_private, stable_id)| field_hash(is_private ? TYPE_DE_CHAMP_PRIVATE : TYPE_DE_CHAMP, stable_id.to_s, label: libelle) } + .map { |(libelle, is_private, stable_id)| field_hash(is_private ? TYPE_DE_CHAMP_PRIVATE : TYPE_DE_CHAMP, stable_id.to_s, label: libelle, type: :text) } fields end @@ -89,7 +102,9 @@ class ProcedurePresentation < ApplicationRecord end def filterable_fields_options - fields.map { |field| [field['label'], field_id(field)] } + fields.map do |field| + [field['label'], field_id(field)] + end end def displayed_fields_for_headers @@ -152,14 +167,21 @@ class ProcedurePresentation < ApplicationRecord end def filtered_ids(dossiers, statut) - filters[statut].group_by { |filter| filter.values_at(TABLE, COLUMN) } .map do |(table, column), filters| + filters.fetch(statut) + .group_by { |filter| filter.values_at(TABLE, COLUMN) } + .map do |(table, column), filters| values = filters.pluck('value') case table when 'self' - dates = values - .filter_map { |v| Time.zone.parse(v).beginning_of_day rescue nil } + field = self_fields.find { |h| h['column'] == column } + if field['type'] == :date + dates = values + .filter_map { |v| Time.zone.parse(v).beginning_of_day rescue nil } - dossiers.filter_by_datetimes(column, dates) + dossiers.filter_by_datetimes(column, dates) + else + dossiers.where("dossiers.#{column} = ?", values) + end when TYPE_DE_CHAMP dossiers.with_type_de_champ(column) .filter_ilike(:champs, :value, values) @@ -282,6 +304,14 @@ class ProcedurePresentation < ApplicationRecord slice(:filters, :sort, :displayed_fields) end + def field_type(field_id) + find_field(*field_id.split(SLASH))['type'] + end + + def field_enum(field_id) + find_field(*field_id.split(SLASH))['scope'] + end + private def field_id(field) @@ -342,13 +372,15 @@ class ProcedurePresentation < ApplicationRecord end end - def field_hash(table, column, label: nil, classname: '', virtual: false) + def field_hash(table, column, label: nil, classname: '', virtual: false, type: :text, scope: '') { 'label' => label || I18n.t(column, scope: [:activerecord, :attributes, :procedure_presentation, :fields, table]), TABLE => table, COLUMN => column, 'classname' => classname, - 'virtual' => virtual + 'virtual' => virtual, + 'type' => type, + 'scope' => scope } end diff --git a/app/views/instructeurs/procedures/_dossiers_filter.html.haml b/app/views/instructeurs/procedures/_dossiers_filter.html.haml index 74bf6dcea..9071d02c1 100644 --- a/app/views/instructeurs/procedures/_dossiers_filter.html.haml +++ b/app/views/instructeurs/procedures/_dossiers_filter.html.haml @@ -2,15 +2,7 @@ %button.button.dropdown-button{ data: { menu_button_target: 'button' } } = t('views.instructeurs.dossiers.filters.title') #filter-menu.dropdown-content.left-aligned.fade-in-down{ data: { menu_button_target: 'menu' } } - = form_tag add_filter_instructeur_procedure_path(procedure), method: :post, class: 'dropdown-form large' do - = label_tag :field, t('views.instructeurs.dossiers.filters.column') - = select_tag :field, options_for_select(filterable_fields_for_select) - %br - = label_tag :value, t('views.instructeurs.dossiers.filters.value') - = text_field_tag :value, nil, maxlength: ProcedurePresentation::FILTERS_VALUE_MAX_LENGTH - = hidden_field_tag :statut, statut - %br - = submit_tag t('views.instructeurs.dossiers.filters.add_filter'), class: 'button' + = render Dossiers::FilterComponent.new(procedure: procedure, procedure_presentation: @procedure_presentation, statut: statut) - current_filters.group_by { |filter| filter['table'] }.each_with_index do |(table, filters), i| - if i > 0 diff --git a/app/views/instructeurs/procedures/add_filter.turbo_stream.haml b/app/views/instructeurs/procedures/add_filter.turbo_stream.haml new file mode 100644 index 000000000..05598d95b --- /dev/null +++ b/app/views/instructeurs/procedures/add_filter.turbo_stream.haml @@ -0,0 +1,2 @@ += turbo_stream.replace 'filter-component' do + = render Dossiers::FilterComponent.new(procedure: @procedure, procedure_presentation: @procedure_presentation, statut: @statut, field_id: @field) diff --git a/config/i18n-tasks.yml b/config/i18n-tasks.yml index 702153547..4e4779796 100644 --- a/config/i18n-tasks.yml +++ b/config/i18n-tasks.yml @@ -106,6 +106,7 @@ ignore_unused: - 'pluralize.*' - 'views.pagination.*' - 'time.formats.default' +- 'instructeurs.dossiers.filterable_state.*' # - '{devise,kaminari,will_paginate}.*' # - 'simple_form.{yes,no}' # - 'simple_form.{placeholders,hints,labels}.*' diff --git a/config/locales/en.yml b/config/locales/en.yml index 9b35c0651..7a74984f7 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -174,9 +174,6 @@ en: deleted_by_administration: "File deleted by administration" restore: "Restore" filters: - column: Column - value: Value - add_filter: Add filter title: Filter personalize: Personalize follow_file: Follow-up the file diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 768c715d1..572366471 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -169,9 +169,6 @@ fr: deleted_by_administration: "Dossier supprimé par l'administration" restore: "Restaurer" filters: - column: Colonne - value: Valeur - add_filter: Ajouter le filtre title: Filtrer personalize: Personnaliser download: Télécharger un dossier diff --git a/config/locales/models/procedure_presentation/en.yml b/config/locales/models/procedure_presentation/en.yml index 55dbe127a..48cbb41a6 100644 --- a/config/locales/models/procedure_presentation/en.yml +++ b/config/locales/models/procedure_presentation/en.yml @@ -7,11 +7,16 @@ en: id: File Nº state: State created_at: Created on - en_construction_at: En construction le - depose_at: Submitted on updated_at: Updated on - depose_since: Submitted since + depose_at: First submission on + en_construction_at: Submitted on + en_instruction_at: En instruction on + processed_at: Done on + depose_since: First Submission since updated_since: Updated since + en_construction_since: Submitted since + en_instruction_since: Instructed since + processed_since: Finished since user: email: Requester followers_instructeurs: diff --git a/config/locales/models/procedure_presentation/fr.yml b/config/locales/models/procedure_presentation/fr.yml index fb6a1155a..6a3496ded 100644 --- a/config/locales/models/procedure_presentation/fr.yml +++ b/config/locales/models/procedure_presentation/fr.yml @@ -7,11 +7,16 @@ fr: id: Nº dossier state: Statut created_at: Créé le - en_construction_at: En construction le - depose_at: Déposé le updated_at: Mis à jour le - depose_since: Déposé depuis + depose_at: Déposé le + en_construction_at: En construction le + en_instruction_at: En instruction le + processed_at: Terminé le updated_since: Mis à jour depuis + depose_since: Déposé depuis + en_construction_since: En construction depuis + en_instruction_since: En instruction depuis + processed_since: Terminé depuis user: email: Demandeur followers_instructeurs: diff --git a/config/locales/views/instructeurs/en.yml b/config/locales/views/instructeurs/en.yml index 49ea80d96..a9c74eb7c 100644 --- a/config/locales/views/instructeurs/en.yml +++ b/config/locales/views/instructeurs/en.yml @@ -3,3 +3,23 @@ en: procedure: archive_pending_html: Archive creation pending
(requested %{created_period} ago) archive_ready_html: Download archive
(requested %{generated_period} ago) + dossiers: + decisions_rendues_block: + without_email: + en_construction: The file had been sent at %{processed_at} + en_instruction: The file had been on instruction at %{processed_at} + accepte: The file had been accepted at %{processed_at} + refuse: The file file hadd been refused at %{processed_at} + classe_sans_suite: The file had been filed away at %{processed_at} + with_email: + en_construction: '%{email} sent this file at %{processed_at}' + en_instruction: '%{email} started this file the instruction at %{processed_at}' + accepte: '%{email} accepted this file at %{processed_at}' + refuse: '%{email} refused this file at %{processed_at}' + classe_sans_suite: '%{email} filed away this file at %{processed_at}' + filterable_state: + en_construction: "In progress" + en_instruction: "Processing" + accepte: "Accepted" + refuse: "Refused" + sans_suite: "No further action" diff --git a/config/locales/views/instructeurs/fr.yml b/config/locales/views/instructeurs/fr.yml index 153dbc679..2d9b8dbb8 100644 --- a/config/locales/views/instructeurs/fr.yml +++ b/config/locales/views/instructeurs/fr.yml @@ -4,8 +4,6 @@ fr: archive_pending_html: Archive en cours de création
(demandée il y a %{created_period}) archive_ready_html: Télécharger l’archive
(demandée il y a %{generated_period}) dossiers: - extend_conservation: - archived_dossier: "Le dossier sera conservé 1 mois supplémentaire" decisions_rendues_block: without_email: en_construction: Le %{processed_at} ce dossier a été passé en construction @@ -19,3 +17,9 @@ fr: accepte: Le %{processed_at}, %{email} a accepté ce dossier refuse: Le %{processed_at}, %{email} a refusé ce dossier classe_sans_suite: Le %{processed_at}, %{email} a classé ce dossier sans suite + filterable_state: + en_construction: "En construction" + en_instruction: "En instruction" + accepte: "Accepté" + refuse: "Refusé" + sans_suite: "Classé sans suite" diff --git a/spec/models/procedure_presentation_spec.rb b/spec/models/procedure_presentation_spec.rb index e59176696..b0f9dced7 100644 --- a/spec/models/procedure_presentation_spec.rb +++ b/spec/models/procedure_presentation_spec.rb @@ -58,28 +58,34 @@ describe ProcedurePresentation do let(:tdc_private_2) { procedure.types_de_champ_private[1] } let(:expected) { [ - { "label" => 'Créé le', "table" => 'self', "column" => 'created_at', 'classname' => '', 'virtual' => false }, - { "label" => 'En construction le', "table" => 'self', "column" => 'en_construction_at', 'classname' => '', 'virtual' => false }, - { "label" => 'Déposé le', "table" => 'self', "column" => 'depose_at', 'classname' => '', 'virtual' => false }, - { "label" => 'Mis à jour le', "table" => 'self', "column" => 'updated_at', 'classname' => '', 'virtual' => false }, - { "label" => "Déposé depuis", "table" => "self", "column" => "depose_since", "classname" => "", 'virtual' => true }, - { "label" => "Mis à jour depuis", "table" => "self", "column" => "updated_since", "classname" => "", 'virtual' => true }, - { "label" => 'Demandeur', "table" => 'user', "column" => 'email', 'classname' => '', 'virtual' => false }, - { "label" => 'Email instructeur', "table" => 'followers_instructeurs', "column" => 'email', 'classname' => '', 'virtual' => false }, - { "label" => 'Groupe instructeur', "table" => 'groupe_instructeur', "column" => 'label', 'classname' => '', 'virtual' => false }, - { "label" => 'SIREN', "table" => 'etablissement', "column" => 'entreprise_siren', 'classname' => '', 'virtual' => false }, - { "label" => 'Forme juridique', "table" => 'etablissement', "column" => 'entreprise_forme_juridique', 'classname' => '', 'virtual' => false }, - { "label" => 'Nom commercial', "table" => 'etablissement', "column" => 'entreprise_nom_commercial', 'classname' => '', 'virtual' => false }, - { "label" => 'Raison sociale', "table" => 'etablissement', "column" => 'entreprise_raison_sociale', 'classname' => '', 'virtual' => false }, - { "label" => 'SIRET siège social', "table" => 'etablissement', "column" => 'entreprise_siret_siege_social', 'classname' => '', 'virtual' => false }, - { "label" => 'Date de création', "table" => 'etablissement', "column" => 'entreprise_date_creation', 'classname' => '', 'virtual' => false }, - { "label" => 'SIRET', "table" => 'etablissement', "column" => 'siret', 'classname' => '', 'virtual' => false }, - { "label" => 'Libellé NAF', "table" => 'etablissement', "column" => 'libelle_naf', 'classname' => '', 'virtual' => false }, - { "label" => 'Code postal', "table" => 'etablissement', "column" => 'code_postal', 'classname' => '', 'virtual' => false }, - { "label" => tdc_1.libelle, "table" => 'type_de_champ', "column" => tdc_1.stable_id.to_s, 'classname' => '', 'virtual' => false }, - { "label" => tdc_2.libelle, "table" => 'type_de_champ', "column" => tdc_2.stable_id.to_s, 'classname' => '', 'virtual' => false }, - { "label" => tdc_private_1.libelle, "table" => 'type_de_champ_private', "column" => tdc_private_1.stable_id.to_s, 'classname' => '', 'virtual' => false }, - { "label" => tdc_private_2.libelle, "table" => 'type_de_champ_private', "column" => tdc_private_2.stable_id.to_s, 'classname' => '', 'virtual' => false } + { "label" => 'Créé le', "table" => 'self', "column" => 'created_at', 'classname' => '', 'virtual' => false, 'type' => :date, "scope" => '' }, + { "label" => 'Mis à jour le', "table" => 'self', "column" => 'updated_at', 'classname' => '', 'virtual' => false, 'type' => :date, "scope" => '' }, + { "label" => 'Déposé le', "table" => 'self', "column" => 'depose_at', 'classname' => '', 'virtual' => false, 'type' => :date, "scope" => '' }, + { "label" => 'En construction le', "table" => 'self', "column" => 'en_construction_at', 'classname' => '', 'virtual' => false, 'type' => :date, "scope" => '' }, + { "label" => 'En instruction le', "table" => 'self', "column" => 'en_instruction_at', 'classname' => '', 'virtual' => false, 'type' => :date, "scope" => '' }, + { "label" => 'Terminé le', "table" => 'self', "column" => 'processed_at', 'classname' => '', 'virtual' => false, 'type' => :date, "scope" => '' }, + { "label" => "Mis à jour depuis", "table" => "self", "column" => "updated_since", "classname" => "", 'virtual' => true, 'type' => :date, 'scope' => '' }, + { "label" => "Déposé depuis", "table" => "self", "column" => "depose_since", "classname" => "", 'virtual' => true, 'type' => :date, 'scope' => '' }, + { "label" => "En construction depuis", "table" => "self", "column" => "en_construction_since", "classname" => "", 'virtual' => true, 'type' => :date, 'scope' => '' }, + { "label" => "En instruction depuis", "table" => "self", "column" => "en_instruction_since", "classname" => "", 'virtual' => true, 'type' => :date, 'scope' => '' }, + { "label" => "Terminé depuis", "table" => "self", "column" => "processed_since", "classname" => "", 'virtual' => true, 'type' => :date, 'scope' => '' }, + { "label" => "Statut", "table" => "self", "column" => "state", "classname" => "", 'virtual' => false, 'scope' => 'instructeurs.dossiers.filterable_state', 'type' => :enum }, + { "label" => 'Demandeur', "table" => 'user', "column" => 'email', 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '' }, + { "label" => 'Email instructeur', "table" => 'followers_instructeurs', "column" => 'email', 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '' }, + { "label" => 'Groupe instructeur', "table" => 'groupe_instructeur', "column" => 'label', 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '' }, + { "label" => 'SIREN', "table" => 'etablissement', "column" => 'entreprise_siren', 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '' }, + { "label" => 'Forme juridique', "table" => 'etablissement', "column" => 'entreprise_forme_juridique', 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '' }, + { "label" => 'Nom commercial', "table" => 'etablissement', "column" => 'entreprise_nom_commercial', 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '' }, + { "label" => 'Raison sociale', "table" => 'etablissement', "column" => 'entreprise_raison_sociale', 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '' }, + { "label" => 'SIRET siège social', "table" => 'etablissement', "column" => 'entreprise_siret_siege_social', 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '' }, + { "label" => 'Date de création', "table" => 'etablissement', "column" => 'entreprise_date_creation', 'classname' => '', 'virtual' => false, 'type' => :date, "scope" => '' }, + { "label" => 'SIRET', "table" => 'etablissement', "column" => 'siret', 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '' }, + { "label" => 'Libellé NAF', "table" => 'etablissement', "column" => 'libelle_naf', 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '' }, + { "label" => 'Code postal', "table" => 'etablissement', "column" => 'code_postal', 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '' }, + { "label" => tdc_1.libelle, "table" => 'type_de_champ', "column" => tdc_1.stable_id.to_s, 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '' }, + { "label" => tdc_2.libelle, "table" => 'type_de_champ', "column" => tdc_2.stable_id.to_s, 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '' }, + { "label" => tdc_private_1.libelle, "table" => 'type_de_champ_private', "column" => tdc_private_1.stable_id.to_s, 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '' }, + { "label" => tdc_private_2.libelle, "table" => 'type_de_champ_private', "column" => tdc_private_2.stable_id.to_s, 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '' } ] } @@ -96,9 +102,9 @@ describe ProcedurePresentation do end context 'when the procedure is for individuals' do - let(:name_field) { { "label" => "Prénom", "table" => "individual", "column" => "prenom", 'classname' => '', 'virtual' => false } } - let(:surname_field) { { "label" => "Nom", "table" => "individual", "column" => "nom", 'classname' => '', 'virtual' => false } } - let(:gender_field) { { "label" => "Civilité", "table" => "individual", "column" => "gender", 'classname' => '', 'virtual' => false } } + let(:name_field) { { "label" => "Prénom", "table" => "individual", "column" => "prenom", 'classname' => '', 'virtual' => false, "type" => :text, "scope" => '' } } + let(:surname_field) { { "label" => "Nom", "table" => "individual", "column" => "nom", 'classname' => '', 'virtual' => false, "type" => :text, "scope" => '' } } + let(:gender_field) { { "label" => "Civilité", "table" => "individual", "column" => "gender", 'classname' => '', 'virtual' => false, "type" => :text, "scope" => '' } } let(:procedure) { create(:procedure, :for_individual) } let(:procedure_presentation) { create(:procedure_presentation, assign_to: assign_to) } diff --git a/spec/system/instructeurs/procedure_filters_spec.rb b/spec/system/instructeurs/procedure_filters_spec.rb index 84caa1b91..7195cbb50 100644 --- a/spec/system/instructeurs/procedure_filters_spec.rb +++ b/spec/system/instructeurs/procedure_filters_spec.rb @@ -77,12 +77,26 @@ describe "procedure filters" do end end + scenario "should be able to user custom fiters", js: true do + # use date filter + click_on 'Filtrer' + select "En construction le", from: "Colonne" + find("input#value[type=date]", visible: true) + fill_in "Valeur", with: "10/10/2010" + click_button "Ajouter le filtre" + + # use enum filter + click_on 'Filtrer' + select "Statut", from: "Colonne" + find("select#value", visible: false) + select 'En construction', from: "Valeur" + click_button "Ajouter le filtre" + end + scenario "should be able to add and remove two filters for the same field", js: true do add_filter(type_de_champ.libelle, champ.value) add_filter(type_de_champ.libelle, champ_2.value) - expect(page).to have_content("#{type_de_champ.libelle} : #{champ.value}") - within ".dossiers-table" do expect(page).to have_link(new_unfollow_dossier.id.to_s, exact: true) expect(page).to have_link(new_unfollow_dossier.user.email) @@ -106,7 +120,6 @@ describe "procedure filters" do within ".dossiers-table" do expect(page).to have_link(new_unfollow_dossier.id.to_s, exact: true) expect(page).to have_link(new_unfollow_dossier.user.email) - expect(page).to have_link(new_unfollow_dossier_2.id.to_s, exact: true) expect(page).to have_link(new_unfollow_dossier_2.user.email) end