From 56003508a79964eb92ea393cd22c935b730b492c Mon Sep 17 00:00:00 2001 From: f Date: Mon, 20 May 2024 14:12:53 -0300 Subject: [PATCH] feat: poder crear un post relacionado in situ --- app/controllers/posts_controller.rb | 33 ++++++++++++--- app/views/posts/_htmx_form.haml | 41 +++++++++++++++++++ app/views/posts/attributes/_new_has_many.haml | 7 +++- app/views/posts/form.haml | 2 +- app/views/posts/new_has_many_value.haml | 2 + 5 files changed, 77 insertions(+), 8 deletions(-) create mode 100644 app/views/posts/_htmx_form.haml create mode 100644 app/views/posts/new_has_many_value.haml diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 93a9983b..ff3ecb8e 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -44,6 +44,7 @@ class PostsController < ApplicationController # estamos creando. def form uuid = params.permit(:uuid).try(:[], :uuid) + locale @post = if uuid.present? @@ -53,12 +54,7 @@ class PostsController < ApplicationController site.posts(lang: locale).build(layout: params.require(:layout)) end - triggers = {} - params.permit(:show, :hide).each_pair do |key, value| - triggers["modal:#{key}"] = { id: value } - end - - headers['HX-Trigger-After-Swap'] = triggers.to_json if triggers.present? + swap_modals render layout: false end @@ -118,7 +114,23 @@ class PostsController < ApplicationController if @post.persisted? site.touch forget_content + end + # @todo Enviar la creación a otro endpoint para evitar tantas + # condiciones. + if htmx? + if @post.persisted? + swap_modals + + @value = @post.title.value + @uuid = @post.uuid.value + @name = params.require(:name) + + render 'posts/new_has_many_value', layout: false + else + # @todo Mostrar errores + end + elsif @post.persisted? redirect_to site_post_path(@site, @post) else render 'posts/new' @@ -216,4 +228,13 @@ class PostsController < ApplicationController def service_for_direct_upload session[:service_name] = site.name.to_sym end + + # @param triggers [Hash] Otros disparadores + def swap_modals(triggers = {}) + params.permit(:show, :hide).each_pair do |key, value| + triggers["modal:#{key}"] = { id: value } + end + + headers['HX-Trigger'] = triggers.to_json if triggers.present? + end end diff --git a/app/views/posts/_htmx_form.haml b/app/views/posts/_htmx_form.haml new file mode 100644 index 00000000..25c45aad --- /dev/null +++ b/app/views/posts/_htmx_form.haml @@ -0,0 +1,41 @@ +-# + El formulario del artículo, con HTMX activado. + + @param :site [Site] + @param :post [Post] + @param :locale [Symbol, String] + @param :dir [Symbol, String] +:ruby + options = { + multipart: true, + class: 'form post ', + 'hx-swap': params.require(:swap), + 'hx-target': "##{params.require(:target)}" + } + + if post.new? + url = options[:'hx-post'] = site_posts_path(site, locale: locale) + options[:class] += 'new' + else + url = options[:'hx-patch'] = site_post_path(site, post.id, locale: locale) + options[:method] = :patch + options[:class] += 'edit' + end + += form_tag url, **options do + -# Parámetros para HTMX + %input{ type: 'hidden', name: 'hide', value: params.require(:show) } + %input{ type: 'hidden', name: 'show', value: params.require(:hide) } + %input{ type: 'hidden', name: 'name', value: params.require(:name) } + %input{ type: 'hidden', name: 'base', value: params.require(:base) } + + -# Botones de guardado + = render 'posts/submit', site: site, post: post + + = hidden_field_tag "#{base}[layout]", post.layout.name + + -# Dibuja cada atributo + = render 'posts/attributes', site: site, post: post, dir: dir, base: base, locale: locale + + -# Botones de guardado + = render 'posts/submit', site: site, post: post diff --git a/app/views/posts/attributes/_new_has_many.haml b/app/views/posts/attributes/_new_has_many.haml index f349fd6c..16d68322 100644 --- a/app/views/posts/attributes/_new_has_many.haml +++ b/app/views/posts/attributes/_new_has_many.haml @@ -16,6 +16,7 @@ post_form_id = "post-form-#{Nanoid.generate}" post_modal_id = "post-modal-#{Nanoid.generate}" post_form_loaded_id = "post-loaded-#{Nanoid.generate}" + value_list_id = "#{id}_body" %div{ id: modal_id, data: { controller: 'modal array', 'array-original-value': metadata.value.to_json, 'array-new-array-value': site_posts_new_related_post_path(site) } } .form-group @@ -45,7 +46,7 @@ %input.form-control{ data: { target: 'array.search', action: 'input->array#search' }, type: 'search', placeholder: t('.filter') } - content_for :"#{id}_body" do - .form-group.mb-0{ id: "#{id}_body" } + .form-group.mb-0{ id: value_list_id } - metadata.values.each_pair do |value, uuid| .mb-2{ data: { target: 'array.item', 'searchable-value': value.remove_diacritics.downcase, value: uuid } } = render 'bootstrap/custom_checkbox', name: name, id: "value-#{Nanoid.generate}", value: uuid, checked: metadata.value.include?(uuid), content: value @@ -81,6 +82,10 @@ %form{ id: post_form_id, 'hx-get': site_posts_form_path(site), 'hx-target': "##{post_form_loaded_id}" } %input{ type: 'hidden', name: 'show', value: post_modal_id } %input{ type: 'hidden', name: 'hide', value: modal_id } + %input{ type: 'hidden', name: 'target', value: value_list_id } + %input{ type: 'hidden', name: 'swap', value: 'beforeend' } + %input{ type: 'hidden', name: 'base', value: id } + %input{ type: 'hidden', name: 'name', value: name } %div{ id: post_modal_id, data: { controller: 'modal' } } = render 'bootstrap/modal', id: post_id, modal_content_attributes: { class: 'h-100' } do - content_for :"#{post_id}_body" do diff --git a/app/views/posts/form.haml b/app/views/posts/form.haml index 36d15fde..df4369e1 100644 --- a/app/views/posts/form.haml +++ b/app/views/posts/form.haml @@ -4,4 +4,4 @@ @param :site [Site] @param :post [Post] -= render 'posts/form', site: @site, post: @post += render 'posts/htmx_form', site: @site, post: @post, locale: @locale, dir: t("locales.#{@locale}.dir"), base: params.require(:base) diff --git a/app/views/posts/new_has_many_value.haml b/app/views/posts/new_has_many_value.haml new file mode 100644 index 00000000..b26acc89 --- /dev/null +++ b/app/views/posts/new_has_many_value.haml @@ -0,0 +1,2 @@ +.mb-2{ data: { target: 'array.item', 'searchable-value': @value.remove_diacritics.downcase, value: @uuid } } + = render 'bootstrap/custom_checkbox', name: @name, id: "value-#{Nanoid.generate}", value: @uuid, checked: true, content: @value