From 9b7b59f67e0491c7815cc97add330f64bced4194 Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Thu, 17 Jan 2019 15:15:46 +0100 Subject: [PATCH] Champs editor should handle repetition type --- app/assets/stylesheets/new_design/flex.scss | 8 +++ .../new_design/procedure_champs_editor.scss | 19 +------ .../procedures_controller.rb | 11 ++-- app/helpers/procedure_helper.rb | 13 +++-- .../administrateur/DraggableItem.js | 40 +++++++++++++-- .../administrateur/DraggableItem.vue | 46 +++++++++++++---- .../administrateur/DraggableList.js | 1 + .../administrateur/DraggableList.vue | 1 - .../administrateur/champs-editor.js | 3 +- app/models/type_de_champ.rb | 4 +- .../procedures/update.js.erb | 2 +- .../features/admin/procedure_creation_spec.rb | 4 +- .../new_administrateur/procedures_spec.rb | 51 +++++++++++++++---- 13 files changed, 148 insertions(+), 55 deletions(-) diff --git a/app/assets/stylesheets/new_design/flex.scss b/app/assets/stylesheets/new_design/flex.scss index e61a57611..317ebf55c 100644 --- a/app/assets/stylesheets/new_design/flex.scss +++ b/app/assets/stylesheets/new_design/flex.scss @@ -28,4 +28,12 @@ &.wrap { flex-wrap: wrap; } + + &.column { + flex-direction: column; + } +} + +.flex-grow { + flex-grow: 1; } diff --git a/app/assets/stylesheets/new_design/procedure_champs_editor.scss b/app/assets/stylesheets/new_design/procedure_champs_editor.scss index 5e1241f38..daa960e59 100644 --- a/app/assets/stylesheets/new_design/procedure_champs_editor.scss +++ b/app/assets/stylesheets/new_design/procedure_champs_editor.scss @@ -9,10 +9,6 @@ } .draggable-item { - display: flex; - flex-direction: column; - justify-content: flex-start; - border: 1px solid $border-grey; border-radius: 5px; margin-bottom: 10px; @@ -55,20 +51,7 @@ } } - .column { - display: flex; - justify-content: flex-start; - flex-direction: column; - - &.shift-left { - margin-left: 35px; - } - } - - .row { - display: flex; - justify-content: flex-start; - + .flex { &.section { padding: 10px 10px 0 10px; margin-bottom: 8px; diff --git a/app/controllers/new_administrateur/procedures_controller.rb b/app/controllers/new_administrateur/procedures_controller.rb index 02566fe80..ff4734397 100644 --- a/app/controllers/new_administrateur/procedures_controller.rb +++ b/app/controllers/new_administrateur/procedures_controller.rb @@ -3,7 +3,7 @@ module NewAdministrateur before_action :retrieve_procedure, only: [:champs, :annotations, :update] before_action :procedure_locked?, only: [:champs, :annotations, :update] - TYPE_DE_CHAMP_ATTRIBUTES = [ + TYPE_DE_CHAMP_ATTRIBUTES_BASE = [ :_destroy, :libelle, :description, @@ -18,6 +18,11 @@ module NewAdministrateur drop_down_list_attributes: [:value] ] + TYPE_DE_CHAMP_ATTRIBUTES = TYPE_DE_CHAMP_ATTRIBUTES_BASE.dup + TYPE_DE_CHAMP_ATTRIBUTES << { + types_de_champ_attributes: TYPE_DE_CHAMP_ATTRIBUTES_BASE + } + def apercu @dossier = procedure_without_control.new_dossier @tab = apercu_tab @@ -26,9 +31,9 @@ module NewAdministrateur def update if @procedure.update(procedure_params) flash.now.notice = if params[:procedure][:types_de_champ_attributes].present? - 'Champs enregistrés' + 'Formulaire mis à jour.' elsif params[:procedure][:types_de_champ_private_attributes].present? - 'Annotations enregistrés' + 'Annotations privées mises à jour.' else 'Démarche enregistrée.' end diff --git a/app/helpers/procedure_helper.rb b/app/helpers/procedure_helper.rb index c6d6db847..443626b8e 100644 --- a/app/helpers/procedure_helper.rb +++ b/app/helpers/procedure_helper.rb @@ -79,9 +79,16 @@ module ProcedureHelper types_de_champ end + TYPES_DE_CHAMP_INCLUDE = { drop_down_list: { only: :value } } + TYPES_DE_CHAMP_BASE = { + except: [:created_at, :updated_at, :stable_id, :type, :parent_id, :procedure_id, :private], + methods: [:piece_justificative_template_filename, :piece_justificative_template_url], + include: TYPES_DE_CHAMP_INCLUDE + } + TYPES_DE_CHAMP = TYPES_DE_CHAMP_BASE + .merge(include: TYPES_DE_CHAMP_INCLUDE.merge(types_de_champ: TYPES_DE_CHAMP_BASE)) + def types_de_champ_as_json(types_de_champ) - types_de_champ.as_json(except: [:created_at, :updated_at], - methods: [:piece_justificative_template_filename, :piece_justificative_template_url], - include: { drop_down_list: { only: :value } }) + types_de_champ.as_json(TYPES_DE_CHAMP) end end diff --git a/app/javascript/new_design/administrateur/DraggableItem.js b/app/javascript/new_design/administrateur/DraggableItem.js index 70dee126f..e1ff2a357 100644 --- a/app/javascript/new_design/administrateur/DraggableItem.js +++ b/app/javascript/new_design/administrateur/DraggableItem.js @@ -1,5 +1,5 @@ export default { - props: ['state', 'update', 'index', 'item', 'prefix'], + props: ['state', 'update', 'index', 'item'], computed: { isDirty() { return ( @@ -56,6 +56,9 @@ export default { isHeaderSection() { return this.typeChamp === 'header_section'; }, + isRepetition() { + return this.typeChamp === 'repetition'; + }, options() { const options = this.item.options || {}; for (let key of Object.keys(options)) { @@ -69,6 +72,21 @@ export default { } else { return 'types_de_champ_attributes'; } + }, + typesDeChamp() { + return this.item.types_de_champ; + }, + typesDeChampOptions() { + return this.state.typesDeChampOptions.filter( + ([, typeChamp]) => !EXCLUDE_FROM_REPETITION.includes(typeChamp) + ); + }, + stateForRepetition() { + return Object.assign({}, this.state, { + typesDeChamp: this.typesDeChamp, + typesDeChampOptions: this.typesDeChampOptions, + prefix: `${this.state.prefix}[${this.attribute}][${this.index}]` + }); } }, data() { @@ -103,14 +121,30 @@ export default { } }, nameFor(name) { - return `${this.prefix}[${this.attribute}][${this.index}][${name}]`; + return `${this.state.prefix}[${this.attribute}][${this.index}][${name}]`; }, elementIdFor(name) { - return `${this.prefix}_${this.attribute}_${this.index}_${name}`; + const prefix = this.state.prefix.replace(/\[/g, '_').replace(/\]/g, ''); + return `${prefix}_${this.attribute}_${this.index}_${name}`; + }, + addChamp() { + this.typesDeChamp.push({ + type_champ: 'text', + drop_down_list: {}, + types_de_champ: [], + options: {} + }); } } }; +const EXCLUDE_FROM_REPETITION = [ + 'carte', + 'dossier_link', + 'repetition', + 'siret' +]; + const PATHS_TO_WATCH = [ 'typeChamp', 'libelle', diff --git a/app/javascript/new_design/administrateur/DraggableItem.vue b/app/javascript/new_design/administrateur/DraggableItem.vue index 93849ed8d..fbb70a5c8 100644 --- a/app/javascript/new_design/administrateur/DraggableItem.vue +++ b/app/javascript/new_design/administrateur/DraggableItem.vue @@ -4,19 +4,23 @@ -
-
+
+
- +
-
+
Le libellé doit être rempli. @@ -36,8 +40,8 @@
-
-
+
+
-
+
-
+
+
+ + + + + +
diff --git a/app/javascript/new_design/administrateur/DraggableList.js b/app/javascript/new_design/administrateur/DraggableList.js index b680daa52..f28746ffe 100644 --- a/app/javascript/new_design/administrateur/DraggableList.js +++ b/app/javascript/new_design/administrateur/DraggableList.js @@ -5,6 +5,7 @@ export default { this.state.typesDeChamp.push({ type_champ: 'text', drop_down_list: {}, + types_de_champ: [], options: {} }); } diff --git a/app/javascript/new_design/administrateur/DraggableList.vue b/app/javascript/new_design/administrateur/DraggableList.vue index 7832e565b..361d1b098 100644 --- a/app/javascript/new_design/administrateur/DraggableList.vue +++ b/app/javascript/new_design/administrateur/DraggableList.vue @@ -16,7 +16,6 @@ { ordered }, foreign_key: :parent_id, class_name: 'TypeDeChamp', dependent: :destroy store_accessor :options, :cadastres, :quartiers_prioritaires, :parcelles_agricoles, :old_pj @@ -84,7 +84,7 @@ class TypeDeChamp < ApplicationRecord has_one_attached :piece_justificative_template accepts_nested_attributes_for :drop_down_list, update_only: true - accepts_nested_attributes_for :types_de_champ, allow_destroy: true + accepts_nested_attributes_for :types_de_champ, reject_if: proc { |attributes| attributes['libelle'].blank? }, allow_destroy: true validates :libelle, presence: true, allow_blank: false, allow_nil: false validates :type_champ, presence: true, allow_blank: false, allow_nil: false diff --git a/app/views/new_administrateur/procedures/update.js.erb b/app/views/new_administrateur/procedures/update.js.erb index 4aa3bae04..d8423e18a 100644 --- a/app/views/new_administrateur/procedures/update.js.erb +++ b/app/views/new_administrateur/procedures/update.js.erb @@ -1,3 +1,3 @@ <%= render_flash timeout: 6000, fixed: true %> -<%= fire_event(:ProcedureUpdated, procedure_data(@procedure)) %> +<%= fire_event(:ProcedureUpdated, procedure_data(@procedure.reload)) %> diff --git a/spec/features/admin/procedure_creation_spec.rb b/spec/features/admin/procedure_creation_spec.rb index 646382773..f8fd9a74a 100644 --- a/spec/features/admin/procedure_creation_spec.rb +++ b/spec/features/admin/procedure_creation_spec.rb @@ -105,7 +105,7 @@ feature 'As an administrateur I wanna create a new procedure', js: true do end expect(page).to have_selector('#procedure_types_de_champ_attributes_0_libelle') fill_in 'procedure_types_de_champ_attributes_0_libelle', with: 'libelle de champ' - expect(page).to have_content('Champs enregistrés') + expect(page).to have_content('Formulaire mis à jour') within '.footer' do click_on 'Ajouter un champ' @@ -135,7 +135,7 @@ feature 'As an administrateur I wanna create a new procedure', js: true do click_on 'Ajouter un champ' end fill_in 'procedure_types_de_champ_attributes_0_libelle', with: 'libelle de champ' - expect(page).to have_content('Champs enregistrés') + expect(page).to have_content('Formulaire mis à jour') click_on Procedure.last.libelle click_on 'onglet-pieces' diff --git a/spec/features/new_administrateur/procedures_spec.rb b/spec/features/new_administrateur/procedures_spec.rb index ead5f28da..47ba7e66f 100644 --- a/spec/features/new_administrateur/procedures_spec.rb +++ b/spec/features/new_administrateur/procedures_spec.rb @@ -5,6 +5,7 @@ feature 'As an administrateur I edit procedure', js: true do let(:procedure) { create(:procedure) } before do + Flipflop::FeatureSet.current.test!.switch!(:champ_repetition, true) login_as administrateur, scope: :administrateur visit champs_procedure_path(procedure) end @@ -15,14 +16,14 @@ feature 'As an administrateur I edit procedure', js: true do end expect(page).to have_selector('#procedure_types_de_champ_attributes_0_libelle') fill_in 'procedure_types_de_champ_attributes_0_libelle', with: 'libellé de champ' - expect(page).to have_content('Champs enregistrés') + expect(page).to have_content('Formulaire mis à jour') page.refresh within '.footer' do click_on 'Enregistrer' end - expect(page).to have_content('Champs enregistrés') + expect(page).to have_content('Formulaire mis à jour') end it "Add multiple champs" do @@ -34,7 +35,7 @@ feature 'As an administrateur I edit procedure', js: true do end expect(page).not_to have_content('Le libellé doit être rempli.') expect(page).not_to have_content('Modifications non sauvegardées.') - expect(page).not_to have_content('Champs enregistrés') + expect(page).not_to have_content('Formulaire mis à jour') fill_in 'procedure_types_de_champ_attributes_0_libelle', with: 'libellé de champ 0' expect(page).to have_selector('#procedure_types_de_champ_attributes_0_libelle') @@ -44,7 +45,7 @@ feature 'As an administrateur I edit procedure', js: true do expect(page).to have_content('Le libellé doit être rempli.') expect(page).to have_content('Modifications non sauvegardées.') - expect(page).not_to have_content('Champs enregistrés') + expect(page).not_to have_content('Formulaire mis à jour') fill_in 'procedure_types_de_champ_attributes_2_libelle', with: 'libellé de champ 2' within '.draggable-item-3' do @@ -53,12 +54,12 @@ feature 'As an administrateur I edit procedure', js: true do expect(page).to have_content('Le libellé doit être rempli.') expect(page).to have_content('Modifications non sauvegardées.') - expect(page).not_to have_content('Champs enregistrés') + expect(page).not_to have_content('Formulaire mis à jour') fill_in 'procedure_types_de_champ_attributes_1_libelle', with: 'libellé de champ 1' expect(page).not_to have_content('Le libellé doit être rempli.') expect(page).not_to have_content('Modifications non sauvegardées.') - expect(page).to have_content('Champs enregistrés') + expect(page).to have_content('Formulaire mis à jour') page.refresh expect(page).to have_content('Supprimer', count: 3) @@ -69,11 +70,11 @@ feature 'As an administrateur I edit procedure', js: true do click_on 'Ajouter un champ' end fill_in 'procedure_types_de_champ_attributes_0_libelle', with: 'libellé de champ' - expect(page).to have_content('Champs enregistrés') + expect(page).to have_content('Formulaire mis à jour') page.refresh click_on 'Supprimer' - expect(page).to have_content('Champs enregistrés') + expect(page).to have_content('Formulaire mis à jour') expect(page).not_to have_content('Supprimer') page.refresh @@ -87,9 +88,39 @@ feature 'As an administrateur I edit procedure', js: true do expect(page).to have_selector('#procedure_types_de_champ_attributes_0_description') fill_in 'procedure_types_de_champ_attributes_0_description', with: 'déscription du champ' expect(page).to have_content('Le libellé doit être rempli.') - expect(page).not_to have_content('Champs enregistrés') + expect(page).not_to have_content('Formulaire mis à jour') fill_in 'procedure_types_de_champ_attributes_0_libelle', with: 'libellé de champ' - expect(page).to have_content('Champs enregistrés') + expect(page).to have_content('Formulaire mis à jour') + end + + it "Add repetition champ" do + within '.footer' do + click_on 'Ajouter un champ' + end + expect(page).to have_selector('#procedure_types_de_champ_attributes_0_libelle') + select('Bloc répétable', from: 'procedure_types_de_champ_attributes_0_type_champ') + fill_in 'procedure_types_de_champ_attributes_0_libelle', with: 'libellé de champ' + + expect(page).to have_content('Formulaire mis à jour') + page.refresh + + within '.flex-grow' do + click_on 'Ajouter un champ' + end + + fill_in 'procedure_types_de_champ_attributes_0_types_de_champ_attributes_0_libelle', with: 'libellé de champ 1' + + expect(page).to have_content('Formulaire mis à jour') + expect(page).to have_content('Supprimer', count: 2) + + within '.footer' do + click_on 'Ajouter un champ' + end + + select('Bloc répétable', from: 'procedure_types_de_champ_attributes_1_type_champ') + fill_in 'procedure_types_de_champ_attributes_1_libelle', with: 'libellé de champ 2' + + expect(page).to have_content('Supprimer', count: 3) end end