[fix #1033] Procedure Edition: add position field to order the champs

This commit is contained in:
Simon Lehericey 2018-01-09 15:36:23 +01:00
parent 78739ccc6f
commit 1473577131
3 changed files with 119 additions and 12 deletions

View file

@ -2,7 +2,9 @@ class TypesDeChampService
def self.create_update_procedure_params(params, private=false)
attributes = (private ? 'types_de_champ_private_attributes' : 'types_de_champ_attributes')
parameters = params
params_with_ordered_champs = order_champs(params, attributes)
parameters = params_with_ordered_champs
.require(:procedure)
.permit("#{attributes}" => [:libelle, :description, :order_place, :type_champ, :id, :mandatory, :type,
drop_down_list_attributes: [:value, :id]])
@ -22,6 +24,40 @@ class TypesDeChampService
private
def self.order_champs(params, attributes)
tdcas = params[:procedure][attributes].to_a
.map { |_hash_index, tdca| tdca }
tdcas
.select { |tdca| !is_number?(tdca[:custom_order_place]) }
.each { |tdca| tdca[:custom_order_place] = (tdca[:order_place].to_i + 1).to_s }
changed_order_tdcas, ordered_tdcas = tdcas.partition { |tdca| tdca_order_changed?(tdca) }
go_up_tdcas, go_down_tdcas = changed_order_tdcas
.partition { |tdca| tdca[:custom_order_place].to_i < (tdca[:order_place].to_i + 1) }
# needed to make the sort_by work properly
tdcas = go_up_tdcas + ordered_tdcas + go_down_tdcas
ordered_tdcas = tdcas
.sort_by { |tdca| tdca[:custom_order_place].to_i }
.each_with_index { |tdca, index| tdca[:order_place] = index.to_s }
.each_with_index.reduce({}) { |acc, (tdca, hash_index)| acc[hash_index.to_s] = tdca; acc }
params[:procedure][attributes] = ActionController::Parameters.new(ordered_tdcas)
params
end
def self.is_number?(value)
(value =~ /^[0-9]+$/) == 0
end
def self.tdca_order_changed?(tdca)
(tdca[:order_place].to_i + 1) != tdca[:custom_order_place].to_i
end
def self.clean_value value
value.split("\r\n").map{ |v| v.strip }.join("\r\n")
end

View file

@ -38,6 +38,10 @@
= ff.object.button_up(index: ff.index, url: @types_de_champ_facade.move_up_url(ff), private: @types_de_champ_facade.private)
= ff.object.button_down(index: ff.index, url: @types_de_champ_facade.move_down_url(ff), private: @types_de_champ_facade.private)
.form-group
%h4 position
= ff.number_field :custom_order_place, value: (ff.index + 1), length: 999, class: 'form-control', style: 'width: 100px;'
.form-group
%br &nbsp;
- if ff.object.id.nil?

View file

@ -1,10 +1,14 @@
require 'spec_helper'
describe TypesDeChampService do
let(:params) do
ActionController::Parameters.new({
procedure: {
types_de_champ_attributes: {
let(:params) { ActionController::Parameters.new({ procedure: { types_de_champ_attributes: types_de_champ_attributes } }) }
let(:result) { TypesDeChampService.create_update_procedure_params(params) }
describe 'self.create_update_procedure_params' do
describe 'the drop down list attributes' do
let(:types_de_champ_attributes) do
{
"0" => {
libelle: 'top',
drop_down_list_attributes: {
@ -13,18 +17,81 @@ describe TypesDeChampService do
}
}
}
}
})
end
let(:result) { TypesDeChampService.create_update_procedure_params(params) }
describe 'self.create_update_procedure_params' do
describe 'the drop down list attributes' do
subject { result['types_de_champ_attributes']['0']['drop_down_list_attributes'] }
it 'has its value stripped' do
expect(subject['value']).to eq("un\r\ndeux\r\n-- commentaire --\r\ntrois")
end
end
describe 'reorder the fields' do
let(:types_de_champ_attributes) do
{
'0' => { 'libelle' => 'a', 'order_place' => '0', 'custom_order_place' => '1' },
'1' => { 'libelle' => 'b', 'order_place' => '1', 'custom_order_place' => '2' }
}
end
subject { result['types_de_champ_attributes'].to_unsafe_hash }
it { is_expected.to match({ "0" => { 'libelle' => 'a', 'order_place' => '0' }, "1" => { 'libelle' => 'b', 'order_place' => '1' } }) }
context 'when the user specifies a position on one element' do
let(:types_de_champ_attributes) do
{
'0' => { 'libelle' => 'a', 'order_place' => '1', 'custom_order_place' => '1' },
'1' => { 'libelle' => 'b', 'order_place' => '10', 'custom_order_place' => '10' },
'2' => { 'libelle' => 'c', 'order_place' => '11', 'custom_order_place' => '2' }
}
end
it do
is_expected.to match({
'0' => { 'libelle' => 'a', 'order_place' => '0' },
'1' => { 'libelle' => 'c', 'order_place' => '1' },
'2' => { 'libelle' => 'b', 'order_place' => '2' }
})
end
end
context 'when the user puts a champ down' do
let(:types_de_champ_attributes) do
{
'0' => { 'libelle' => 'a', 'order_place' => '0', 'custom_order_place' => '2' },
'1' => { 'libelle' => 'b', 'order_place' => '1', 'custom_order_place' => '2' },
'2' => { 'libelle' => 'c', 'order_place' => '2', 'custom_order_place' => '3' }
}
end
it do
is_expected.to match({
'0' => { 'libelle' => 'b', 'order_place' => '0' },
'1' => { 'libelle' => 'a', 'order_place' => '1' },
'2' => { 'libelle' => 'c', 'order_place' => '2' }
})
end
end
context 'when the user uses not a number' do
let(:types_de_champ_attributes) do
{
'0' => { 'libelle' => 'a', 'order_place' => '0', 'custom_order_place' => '1' },
'1' => { 'libelle' => 'b', 'order_place' => '1', 'custom_order_place' => '2' },
'2' => { 'libelle' => 'c', 'order_place' => '2', 'custom_order_place' => '' },
'3' => { 'libelle' => 'd', 'order_place' => '3', 'custom_order_place' => 'a' }
}
end
it 'does not change the natural order' do
is_expected.to match({
'0' => { 'libelle' => 'a', 'order_place' => '0' },
'1' => { 'libelle' => 'b', 'order_place' => '1' },
'2' => { 'libelle' => 'c', 'order_place' => '2' },
'3' => { 'libelle' => 'd', 'order_place' => '3' }
})
end
end
end
end
end