mirror of
https://0xacab.org/sutty/sutty
synced 2024-11-26 07:16:21 +00:00
feat: new_has_one
This commit is contained in:
parent
ff3042da90
commit
96aebb1346
10 changed files with 104 additions and 11 deletions
|
@ -40,10 +40,18 @@ class PostsController < ApplicationController
|
||||||
render layout: false
|
render layout: false
|
||||||
end
|
end
|
||||||
|
|
||||||
# El formulario de un Post, si pasamos el uuid, estamos editando, sino
|
def new_has_one
|
||||||
|
@uuid = params.require(:value).strip
|
||||||
|
|
||||||
|
@indexed_post = site.indexed_posts.find_by!(post_id: @uuid)
|
||||||
|
|
||||||
|
render layout: false
|
||||||
|
end
|
||||||
|
|
||||||
|
# El formulario de un Post, si pasamos el UUID, estamos editando, sino
|
||||||
# estamos creando.
|
# estamos creando.
|
||||||
def form
|
def form
|
||||||
uuid = params.permit(:uuid).try(:[], :uuid)
|
uuid = params.permit(:uuid).try(:[], :uuid).presence
|
||||||
locale
|
locale
|
||||||
|
|
||||||
@post =
|
@post =
|
||||||
|
@ -111,7 +119,7 @@ class PostsController < ApplicationController
|
||||||
params: params)
|
params: params)
|
||||||
@post = service.create
|
@post = service.create
|
||||||
|
|
||||||
if @post.persisted?
|
if post.persisted?
|
||||||
site.touch
|
site.touch
|
||||||
forget_content
|
forget_content
|
||||||
end
|
end
|
||||||
|
@ -119,11 +127,11 @@ class PostsController < ApplicationController
|
||||||
# @todo Enviar la creación a otro endpoint para evitar tantas
|
# @todo Enviar la creación a otro endpoint para evitar tantas
|
||||||
# condiciones.
|
# condiciones.
|
||||||
if htmx?
|
if htmx?
|
||||||
if @post.persisted?
|
if post.persisted?
|
||||||
swap_modals
|
swap_modals
|
||||||
|
|
||||||
@value = @post.title.value
|
@value = post.title.value
|
||||||
@uuid = @post.uuid.value
|
@uuid = post.uuid.value
|
||||||
@name = params.require(:name)
|
@name = params.require(:name)
|
||||||
|
|
||||||
render render_path_from_attribute, layout: false
|
render render_path_from_attribute, layout: false
|
||||||
|
@ -133,8 +141,8 @@ class PostsController < ApplicationController
|
||||||
|
|
||||||
render 'posts/form', layout: false, post: post, site: site, **params.permit(:form, :base, :dir, :locale)
|
render 'posts/form', layout: false, post: post, site: site, **params.permit(:form, :base, :dir, :locale)
|
||||||
end
|
end
|
||||||
elsif @post.persisted?
|
elsif post.persisted?
|
||||||
redirect_to site_post_path(@site, @post)
|
redirect_to site_post_path(site, post)
|
||||||
else
|
else
|
||||||
render 'posts/new'
|
render 'posts/new'
|
||||||
end
|
end
|
||||||
|
@ -235,7 +243,7 @@ class PostsController < ApplicationController
|
||||||
# @param triggers [Hash] Otros disparadores
|
# @param triggers [Hash] Otros disparadores
|
||||||
def swap_modals(triggers = {})
|
def swap_modals(triggers = {})
|
||||||
params.permit(:show, :hide).each_pair do |key, value|
|
params.permit(:show, :hide).each_pair do |key, value|
|
||||||
triggers["modal:#{key}"] = { id: value }
|
triggers["modal:#{key}"] = { id: value } if value.present?
|
||||||
end
|
end
|
||||||
|
|
||||||
headers['HX-Trigger'] = triggers.to_json if triggers.present?
|
headers['HX-Trigger'] = triggers.to_json if triggers.present?
|
||||||
|
@ -247,6 +255,7 @@ class PostsController < ApplicationController
|
||||||
when 'new_has_many' then 'posts/new_has_many_value'
|
when 'new_has_many' then 'posts/new_has_many_value'
|
||||||
when 'new_belongs_to' then 'posts/new_belongs_to_value'
|
when 'new_belongs_to' then 'posts/new_belongs_to_value'
|
||||||
when 'new_has_and_belongs_to_many' then 'posts/new_has_many_value'
|
when 'new_has_and_belongs_to_many' then 'posts/new_has_many_value'
|
||||||
|
when 'new_has_one' then 'posts/new_has_one_value'
|
||||||
else 'nothing'
|
else 'nothing'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -18,9 +18,23 @@ export default class extends Controller {
|
||||||
window.removeEventListener("modal:hide", this.hideEvent);
|
window.removeEventListener("modal:hide", this.hideEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Abrir otro modal, enviando el ID a toda la ventana.
|
||||||
|
*/
|
||||||
|
showAnother(event = undefined) {
|
||||||
|
event?.preventDefault();
|
||||||
|
|
||||||
|
if (!event.target?.dataset?.modalShowValue) return;
|
||||||
|
|
||||||
|
window.dispatchEvent(new CustomEvent("modal:show", { detail: { id: event.target.dataset.modalShowValue } }));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Podemos enviar la orden de apertura como un click o como un
|
* Podemos enviar la orden de apertura como un click o como un
|
||||||
* CustomEvent incluyendo el id del modal como detail.
|
* CustomEvent incluyendo el id del modal como detail.
|
||||||
|
*
|
||||||
|
* El elemento clicleable puede tener un valor que se refiera a otro
|
||||||
|
* modal también.
|
||||||
*/
|
*/
|
||||||
show(event = undefined) {
|
show(event = undefined) {
|
||||||
event?.preventDefault();
|
event?.preventDefault();
|
||||||
|
|
6
app/models/metadata_new_has_one.rb
Normal file
6
app/models/metadata_new_has_one.rb
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# Nueva interfaz para relaciones 1:1
|
||||||
|
class MetadataNewHasOne < MetadataHasOne
|
||||||
|
include Metadata::UnusedValuesConcern
|
||||||
|
end
|
|
@ -61,8 +61,8 @@
|
||||||
= errors.first
|
= errors.first
|
||||||
|
|
||||||
-# Parámetros para HTMX
|
-# Parámetros para HTMX
|
||||||
%input{ type: 'hidden', name: 'hide', value: params.require((post.errors.empty? ? :show : :hide)) }
|
%input{ type: 'hidden', name: 'hide', value: params.permit((post.errors.empty? ? :show : :hide)).try(:values).try(:first) }
|
||||||
%input{ type: 'hidden', name: 'show', value: params.require((post.errors.empty? ? :hide : :show)) }
|
%input{ type: 'hidden', name: 'show', value: params.permit((post.errors.empty? ? :hide : :show)).try(:values).try(:first) }
|
||||||
%input{ type: 'hidden', name: 'name', value: params.require(:name) }
|
%input{ type: 'hidden', name: 'name', value: params.require(:name) }
|
||||||
%input{ type: 'hidden', name: 'base', value: params.require(:base) }
|
%input{ type: 'hidden', name: 'base', value: params.require(:base) }
|
||||||
%input{ type: 'hidden', name: 'form', value: options[:id] }
|
%input{ type: 'hidden', name: 'form', value: options[:id] }
|
||||||
|
|
2
app/views/posts/_new_has_one.haml
Normal file
2
app/views/posts/_new_has_one.haml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
= render 'posts/new_related_post', post: post
|
||||||
|
%input{ type: 'hidden', name: name, value: value }
|
6
app/views/posts/attribute_ro/_new_has_one.haml
Normal file
6
app/views/posts/attribute_ro/_new_has_one.haml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
%tr{ id: attribute }
|
||||||
|
%th= post_label_t(attribute, post: post)
|
||||||
|
%td{ dir: dir, lang: locale }
|
||||||
|
- p = metadata.has_one
|
||||||
|
- if p
|
||||||
|
= link_to p.title.value, site_post_path(site, p.id)
|
53
app/views/posts/attributes/_new_has_one.haml
Normal file
53
app/views/posts/attributes/_new_has_one.haml
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
-#
|
||||||
|
Genera un listado de radios entre los que se puede elegir solo uno para
|
||||||
|
guardar. Podemos elegir entre los artículos ya cargados o agregar uno
|
||||||
|
nuevo.
|
||||||
|
|
||||||
|
Al agregar uno nuevo, se abre un segundo modal que carga el formulario
|
||||||
|
correspondiente vía HTMX. El formulario tiene que cargarse por fuera
|
||||||
|
del formulario principal porque no se pueden anidar.
|
||||||
|
|
||||||
|
:ruby
|
||||||
|
id = random_id
|
||||||
|
name = "#{base}[#{attribute}]"
|
||||||
|
target_id = random_id
|
||||||
|
form_id = random_id
|
||||||
|
modal_id = random_id
|
||||||
|
post_id = random_id
|
||||||
|
post_form_id = random_id
|
||||||
|
post_modal_id = random_id
|
||||||
|
post_form_loaded_id = random_id
|
||||||
|
value_list_id = random_id
|
||||||
|
layout = metadata.filter[:layout]
|
||||||
|
|
||||||
|
%div{ data: { controller: 'modal' }}
|
||||||
|
.form-group
|
||||||
|
= hidden_field_tag name, ''
|
||||||
|
.d-flex.align-items-center.justify-content-between
|
||||||
|
= label_tag id, post_label_t(attribute, post: post), class: 'h3'
|
||||||
|
= render 'bootstrap/btn', content: t('.edit'), action: 'modal#showAnother', data: { 'modal-show-value': modal_id }
|
||||||
|
|
||||||
|
-# Aquí se reemplaza por la tarjeta y el UUID luego de guardar
|
||||||
|
.row.row-cols-1.no-gutters.placeholder-glow{ id: target_id }
|
||||||
|
-# @todo issue-7537
|
||||||
|
- if !metadata.empty? && (indexed_post = site.indexed_posts.find_by(post_id: metadata.value))
|
||||||
|
= render 'posts/new_has_one', post: indexed_post, name: name, value: metadata.value
|
||||||
|
|
||||||
|
-#
|
||||||
|
El modal se genera por fuera del formulario, para poder enviar los
|
||||||
|
datos y recibir su UUID en respuesta.
|
||||||
|
- content_for :post_form do
|
||||||
|
%div{ id: modal_id, data: { controller: 'modal' }}
|
||||||
|
- if layout.is_a?(String)
|
||||||
|
= render 'bootstrap/modal', id: id, modal_content_attributes: { class: 'h-100' } do
|
||||||
|
- content_for :"#{id}_body" do
|
||||||
|
-# @todo ocultar el modal después de guardar
|
||||||
|
.placeholder-glow{ 'hx-get': site_posts_form_path(site, layout: layout, base: id, name: name, form: form_id, swap: 'innerHTML', target: target_id, attribute: 'new_has_one', hide: modal_id, uuid: metadata.value), 'hx-trigger': 'load' }
|
||||||
|
%span.placeholder.w-100.h-100
|
||||||
|
|
||||||
|
- content_for :"#{id}_footer" do
|
||||||
|
= render 'bootstrap/btn', form: form_id, content: t('.save'), type: 'submit', class: 'm-0 mt-1 mr-1'
|
||||||
|
= render 'bootstrap/btn', content: t('.cancel'), action: 'modal#hide', class: 'm-0 mt-1 mr-1'
|
||||||
|
|
||||||
|
- else
|
||||||
|
Nada
|
1
app/views/posts/new_has_one.haml
Normal file
1
app/views/posts/new_has_one.haml
Normal file
|
@ -0,0 +1 @@
|
||||||
|
= render 'posts/new_has_one', post: @indexed_post, name: params.require(:name), value: @uuid
|
1
app/views/posts/new_has_one_value.haml
Normal file
1
app/views/posts/new_has_one_value.haml
Normal file
|
@ -0,0 +1 @@
|
||||||
|
= render 'posts/new_has_one', post: @post.to_index, name: params.require(:name), value: @uuid
|
|
@ -103,6 +103,7 @@ Rails.application.routes.draw do
|
||||||
get :'posts/new_array', to: 'posts#new_array'
|
get :'posts/new_array', to: 'posts#new_array'
|
||||||
get :'posts/new_array_value', to: 'posts#new_array_value'
|
get :'posts/new_array_value', to: 'posts#new_array_value'
|
||||||
get :'posts/new_related_post', to: 'posts#new_related_post'
|
get :'posts/new_related_post', to: 'posts#new_related_post'
|
||||||
|
get :'posts/new_has_one', to: 'posts#new_has_one'
|
||||||
get :'posts/form', to: 'posts#form'
|
get :'posts/form', to: 'posts#form'
|
||||||
|
|
||||||
resources :posts do
|
resources :posts do
|
||||||
|
|
Loading…
Reference in a new issue