types_de_champ controller to use turbo
This commit is contained in:
parent
cf81e8ecd5
commit
1573d20ee9
12 changed files with 133 additions and 58 deletions
|
@ -1,16 +1,17 @@
|
|||
module Administrateurs
|
||||
class TypesDeChampController < AdministrateurController
|
||||
before_action :retrieve_procedure, only: [:create, :update, :move, :estimate_fill_duration, :destroy]
|
||||
before_action :procedure_revisable?, only: [:create, :update, :move, :destroy]
|
||||
before_action :retrieve_procedure, only: [:create, :update, :move, :move_up, :move_down, :destroy]
|
||||
before_action :procedure_revisable?, only: [:create, :update, :move, :move_up, :move_down, :destroy]
|
||||
|
||||
def create
|
||||
type_de_champ = @procedure.draft_revision.add_type_de_champ(type_de_champ_create_params)
|
||||
|
||||
if type_de_champ.valid?
|
||||
@coordinate = @procedure.draft_revision.coordinate_for(type_de_champ)
|
||||
reset_procedure
|
||||
render json: serialize_type_de_champ(type_de_champ), status: :created
|
||||
flash.notice = "Formulaire enregistré"
|
||||
else
|
||||
render json: { errors: type_de_champ.errors.full_messages }, status: :unprocessable_entity
|
||||
flash.alert = type_de_champ.errors.full_messages
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -18,61 +19,43 @@ module Administrateurs
|
|||
type_de_champ = @procedure.draft_revision.find_and_ensure_exclusive_use(params[:id])
|
||||
|
||||
if type_de_champ.update(type_de_champ_update_params)
|
||||
if params[:should_render]
|
||||
@coordinate = @procedure.draft_revision.coordinate_for(type_de_champ)
|
||||
end
|
||||
reset_procedure
|
||||
render json: serialize_type_de_champ(type_de_champ)
|
||||
flash.notice = "Formulaire enregistré"
|
||||
else
|
||||
render json: { errors: type_de_champ.errors.full_messages }, status: :unprocessable_entity
|
||||
flash.alert = type_de_champ.errors.full_messages
|
||||
end
|
||||
end
|
||||
|
||||
def move
|
||||
flash.notice = "Formulaire enregistré"
|
||||
@procedure.draft_revision.move_type_de_champ(params[:id], params[:position].to_i)
|
||||
|
||||
head :no_content
|
||||
end
|
||||
|
||||
def estimate_fill_duration
|
||||
estimate = @procedure.draft_revision.estimated_fill_duration
|
||||
render json: { estimated_fill_duration: estimate }
|
||||
def move_up
|
||||
flash.notice = "Formulaire enregistré"
|
||||
@coordinate = @procedure.draft_revision.move_up_type_de_champ(params[:id])
|
||||
end
|
||||
|
||||
def move_down
|
||||
flash.notice = "Formulaire enregistré"
|
||||
@coordinate = @procedure.draft_revision.move_down_type_de_champ(params[:id])
|
||||
end
|
||||
|
||||
def destroy
|
||||
@procedure.draft_revision.remove_type_de_champ(params[:id])
|
||||
@coordinate = @procedure.draft_revision.remove_type_de_champ(params[:id])
|
||||
reset_procedure
|
||||
|
||||
head :no_content
|
||||
flash.notice = "Formulaire enregistré"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def serialize_type_de_champ(type_de_champ)
|
||||
{ type_de_champ: type_de_champ.as_json_for_editor }
|
||||
end
|
||||
|
||||
def type_de_champ_create_params
|
||||
params.required(:type_de_champ).permit(:type_champ,
|
||||
:libelle,
|
||||
:description,
|
||||
:mandatory,
|
||||
:parent_id,
|
||||
:private,
|
||||
:drop_down_list_value,
|
||||
:drop_down_other,
|
||||
:drop_down_secondary_libelle,
|
||||
:drop_down_secondary_description,
|
||||
:piece_justificative_template,
|
||||
editable_options: [
|
||||
:cadastres,
|
||||
:unesco,
|
||||
:arretes_protection,
|
||||
:conservatoire_littoral,
|
||||
:reserves_chasse_faune_sauvage,
|
||||
:reserves_biologiques,
|
||||
:reserves_naturelles,
|
||||
:natura_2000,
|
||||
:zones_humides,
|
||||
:znieff
|
||||
])
|
||||
params
|
||||
.required(:type_de_champ)
|
||||
.permit(:type_champ, :parent_id, :private, :libelle, :after_id)
|
||||
end
|
||||
|
||||
def type_de_champ_update_params
|
||||
|
|
|
@ -4,7 +4,7 @@ module TurboStreamHelper
|
|||
end
|
||||
|
||||
class TagBuilder < Turbo::Streams::TagBuilder
|
||||
def dispatch(type, detail)
|
||||
def dispatch(type, detail = {})
|
||||
append_all('turbo-events', partial: 'layouts/turbo_event', locals: { type: type, detail: detail })
|
||||
end
|
||||
|
||||
|
|
|
@ -40,24 +40,26 @@ class ProcedureRevision < ApplicationRecord
|
|||
|
||||
def add_type_de_champ(params)
|
||||
parent_stable_id = params.delete(:parent_id)
|
||||
after_stable_id = params.delete(:after_id)
|
||||
|
||||
coordinate = {}
|
||||
|
||||
if parent_stable_id.present?
|
||||
parent_coordinate, parent = coordinate_and_tdc(parent_stable_id)
|
||||
parent_coordinate, _ = coordinate_and_tdc(parent_stable_id)
|
||||
|
||||
coordinate[:parent_id] = parent_coordinate.id
|
||||
coordinate[:position] = children_of(parent).count
|
||||
coordinate[:position] = last_position(parent_coordinate.revision_types_de_champ, after_stable_id)
|
||||
elsif params[:private]
|
||||
coordinate[:position] = revision_types_de_champ_private.count
|
||||
coordinate[:position] = last_position(revision_types_de_champ_private, after_stable_id)
|
||||
else
|
||||
coordinate[:position] = revision_types_de_champ_public.count
|
||||
coordinate[:position] = last_position(revision_types_de_champ_public, after_stable_id)
|
||||
end
|
||||
|
||||
tdc = TypeDeChamp.new(params)
|
||||
if tdc.save
|
||||
coordinate[:type_de_champ] = tdc
|
||||
revision_types_de_champ.create!(coordinate)
|
||||
coordinate = revision_types_de_champ.create!(coordinate)
|
||||
reorder(coordinate.siblings)
|
||||
end
|
||||
|
||||
tdc
|
||||
|
@ -83,6 +85,9 @@ class ProcedureRevision < ApplicationRecord
|
|||
siblings.insert(position, siblings.delete_at(siblings.index(coordinate)))
|
||||
|
||||
reorder(siblings)
|
||||
coordinate.reload
|
||||
|
||||
coordinate
|
||||
end
|
||||
|
||||
def remove_type_de_champ(stable_id)
|
||||
|
@ -95,6 +100,24 @@ class ProcedureRevision < ApplicationRecord
|
|||
tdc.destroy_if_orphan
|
||||
|
||||
reorder(coordinate.siblings)
|
||||
|
||||
coordinate
|
||||
end
|
||||
|
||||
def move_up_type_de_champ(stable_id)
|
||||
coordinate, _ = coordinate_and_tdc(stable_id)
|
||||
|
||||
if coordinate.position > 0
|
||||
move_type_de_champ(stable_id, coordinate.position - 1)
|
||||
else
|
||||
coordinate
|
||||
end
|
||||
end
|
||||
|
||||
def move_down_type_de_champ(stable_id)
|
||||
coordinate, _ = coordinate_and_tdc(stable_id)
|
||||
|
||||
move_type_de_champ(stable_id, coordinate.position + 1)
|
||||
end
|
||||
|
||||
def draft?
|
||||
|
@ -162,6 +185,10 @@ class ProcedureRevision < ApplicationRecord
|
|||
end
|
||||
end
|
||||
|
||||
def coordinate_for(tdc)
|
||||
revision_types_de_champ.find_by!(type_de_champ: tdc)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def compute_estimated_fill_duration
|
||||
|
@ -189,7 +216,7 @@ class ProcedureRevision < ApplicationRecord
|
|||
|
||||
def reorder(siblings)
|
||||
siblings.to_a.compact.each.with_index do |sibling, position|
|
||||
sibling.update(position: position)
|
||||
sibling.update_column(:position, position)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -426,4 +453,16 @@ class ProcedureRevision < ApplicationRecord
|
|||
coordinate.update!(type_de_champ: cloned_type_de_champ)
|
||||
cloned_type_de_champ
|
||||
end
|
||||
|
||||
def last_position(siblings, after_stable_id = nil)
|
||||
if after_stable_id.present?
|
||||
siblings
|
||||
.joins(:type_de_champ)
|
||||
.find_by(types_de_champ: { stable_id: after_stable_id })
|
||||
.position + 1
|
||||
else
|
||||
last = siblings.last
|
||||
last.present? ? last.position + 1 : 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -16,6 +16,7 @@ class ProcedureRevisionTypeDeChamp < ApplicationRecord
|
|||
|
||||
belongs_to :parent, class_name: 'ProcedureRevisionTypeDeChamp', optional: true
|
||||
has_many :revision_types_de_champ, -> { ordered }, foreign_key: :parent_id, class_name: 'ProcedureRevisionTypeDeChamp', inverse_of: :parent, dependent: :destroy
|
||||
has_one :procedure, through: :revision
|
||||
scope :root, -> { where(parent: nil) }
|
||||
scope :ordered, -> { order(:position) }
|
||||
scope :revision_ordered, -> { order(:revision_id) }
|
||||
|
@ -28,6 +29,14 @@ class ProcedureRevisionTypeDeChamp < ApplicationRecord
|
|||
parent_id.present?
|
||||
end
|
||||
|
||||
def first?
|
||||
position == 0
|
||||
end
|
||||
|
||||
def last?
|
||||
siblings.last == self
|
||||
end
|
||||
|
||||
def siblings
|
||||
if parent_id.present?
|
||||
revision.revision_types_de_champ.where(parent_id: parent_id).ordered
|
||||
|
@ -37,4 +46,19 @@ class ProcedureRevisionTypeDeChamp < ApplicationRecord
|
|||
revision.revision_types_de_champ_public
|
||||
end
|
||||
end
|
||||
|
||||
def previous_sibling
|
||||
index = siblings.index(self)
|
||||
if index > 0
|
||||
siblings[index - 1]
|
||||
end
|
||||
end
|
||||
|
||||
def block
|
||||
if child?
|
||||
parent
|
||||
else
|
||||
revision
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
- sibling = coordinate.previous_sibling
|
||||
|
||||
- if sibling.present?
|
||||
= turbo_stream.after dom_id(sibling, :type_de_champ_editor) do
|
||||
= render TypesDeChampEditor::ChampComponent.new(coordinate: coordinate, focused: true)
|
||||
- else
|
||||
= turbo_stream.prepend dom_id(coordinate.block, :types_de_champ_editor_block) do
|
||||
= render TypesDeChampEditor::ChampComponent.new(coordinate: coordinate, focused: true)
|
||||
= turbo_stream.dispatch 'sortable:sort'
|
|
@ -0,0 +1,2 @@
|
|||
- if @coordinate&.type_de_champ&.valid?
|
||||
= render partial: 'insert', locals: { coordinate: @coordinate }
|
|
@ -0,0 +1,4 @@
|
|||
= turbo_stream.remove dom_id(@coordinate, :type_de_champ_editor)
|
||||
= turbo_stream.dispatch 'sortable:sort'
|
||||
= turbo_stream.morph dom_id(@coordinate.revision, :estimated_fill_duration) do
|
||||
= render TypesDeChampEditor::EstimatedFillDurationComponent.new(revision: @coordinate.revision, is_annotation: @coordinate.private?)
|
|
@ -0,0 +1,2 @@
|
|||
= turbo_stream.remove dom_id(@coordinate, :type_de_champ_editor)
|
||||
= render partial: 'insert', locals: { coordinate: @coordinate }
|
|
@ -0,0 +1,2 @@
|
|||
= turbo_stream.remove dom_id(@coordinate, :type_de_champ_editor)
|
||||
= render partial: 'insert', locals: { coordinate: @coordinate }
|
|
@ -0,0 +1,5 @@
|
|||
- if @coordinate&.type_de_champ&.valid?
|
||||
= turbo_stream.morph dom_id(@coordinate, :type_de_champ_editor) do
|
||||
= render TypesDeChampEditor::ChampComponent.new(coordinate: @coordinate)
|
||||
= turbo_stream.morph dom_id(@coordinate.revision, :estimated_fill_duration) do
|
||||
= render TypesDeChampEditor::EstimatedFillDurationComponent.new(revision: @coordinate.revision, is_annotation: @coordinate.private?)
|
|
@ -469,6 +469,8 @@ Rails.application.routes.draw do
|
|||
end
|
||||
member do
|
||||
patch :move
|
||||
patch :move_up
|
||||
patch :move_down
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
describe Administrateurs::TypesDeChampController, type: :controller do
|
||||
let(:admin) { create(:administrateur) }
|
||||
|
||||
describe '#types_de_champs editor api' do
|
||||
describe '#types_de_champs editor' do
|
||||
let(:procedure) { create(:procedure) }
|
||||
|
||||
before do
|
||||
|
@ -17,12 +17,13 @@ describe Administrateurs::TypesDeChampController, type: :controller do
|
|||
procedure_id: procedure.id,
|
||||
type_de_champ: {
|
||||
type_champ: type_champ,
|
||||
libelle: 'Nouveau champ'
|
||||
libelle: 'Nouveau champ',
|
||||
private: false
|
||||
}
|
||||
}
|
||||
}, format: :turbo_stream
|
||||
end
|
||||
|
||||
it { expect(response).to have_http_status(:created) }
|
||||
it { expect(response).to have_http_status(:ok) }
|
||||
end
|
||||
|
||||
context "validate type_de_champ linked_drop_down_list" do
|
||||
|
@ -33,12 +34,13 @@ describe Administrateurs::TypesDeChampController, type: :controller do
|
|||
procedure_id: procedure.id,
|
||||
type_de_champ: {
|
||||
type_champ: type_champ,
|
||||
libelle: 'Nouveau champ'
|
||||
libelle: 'Nouveau champ',
|
||||
private: false
|
||||
}
|
||||
}
|
||||
}, format: :turbo_stream
|
||||
end
|
||||
|
||||
it { expect(response).to have_http_status(:unprocessable_entity) }
|
||||
it { expect(response).to have_http_status(:ok) }
|
||||
end
|
||||
|
||||
context "create type_de_champ linked_drop_down_list" do
|
||||
|
@ -50,12 +52,13 @@ describe Administrateurs::TypesDeChampController, type: :controller do
|
|||
type_de_champ: {
|
||||
type_champ: type_champ,
|
||||
libelle: 'Nouveau champ',
|
||||
drop_down_list_value: '--value--'
|
||||
drop_down_list_value: '--value--',
|
||||
private: false
|
||||
}
|
||||
}
|
||||
}, format: :turbo_stream
|
||||
end
|
||||
|
||||
it { expect(response).to have_http_status(:created) }
|
||||
it { expect(response).to have_http_status(:ok) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue