mirror of
https://0xacab.org/sutty/sutty
synced 2024-11-22 15:46: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
|
||||
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.
|
||||
def form
|
||||
uuid = params.permit(:uuid).try(:[], :uuid)
|
||||
uuid = params.permit(:uuid).try(:[], :uuid).presence
|
||||
locale
|
||||
|
||||
@post =
|
||||
|
@ -111,7 +119,7 @@ class PostsController < ApplicationController
|
|||
params: params)
|
||||
@post = service.create
|
||||
|
||||
if @post.persisted?
|
||||
if post.persisted?
|
||||
site.touch
|
||||
forget_content
|
||||
end
|
||||
|
@ -119,11 +127,11 @@ class PostsController < ApplicationController
|
|||
# @todo Enviar la creación a otro endpoint para evitar tantas
|
||||
# condiciones.
|
||||
if htmx?
|
||||
if @post.persisted?
|
||||
if post.persisted?
|
||||
swap_modals
|
||||
|
||||
@value = @post.title.value
|
||||
@uuid = @post.uuid.value
|
||||
@value = post.title.value
|
||||
@uuid = post.uuid.value
|
||||
@name = params.require(:name)
|
||||
|
||||
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)
|
||||
end
|
||||
elsif @post.persisted?
|
||||
redirect_to site_post_path(@site, @post)
|
||||
elsif post.persisted?
|
||||
redirect_to site_post_path(site, post)
|
||||
else
|
||||
render 'posts/new'
|
||||
end
|
||||
|
@ -235,7 +243,7 @@ class PostsController < ApplicationController
|
|||
# @param triggers [Hash] Otros disparadores
|
||||
def swap_modals(triggers = {})
|
||||
params.permit(:show, :hide).each_pair do |key, value|
|
||||
triggers["modal:#{key}"] = { id: value }
|
||||
triggers["modal:#{key}"] = { id: value } if value.present?
|
||||
end
|
||||
|
||||
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_belongs_to' then 'posts/new_belongs_to_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'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -18,9 +18,23 @@ export default class extends Controller {
|
|||
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
|
||||
* 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) {
|
||||
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
|
||||
|
||||
-# Parámetros para HTMX
|
||||
%input{ type: 'hidden', name: 'hide', value: params.require((post.errors.empty? ? :show : :hide)) }
|
||||
%input{ type: 'hidden', name: 'show', value: params.require((post.errors.empty? ? :hide : :show)) }
|
||||
%input{ type: 'hidden', name: 'hide', value: params.permit((post.errors.empty? ? :show : :hide)).try(:values).try(:first) }
|
||||
%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: 'base', value: params.require(:base) }
|
||||
%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_value', to: 'posts#new_array_value'
|
||||
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'
|
||||
|
||||
resources :posts do
|
||||
|
|
Loading…
Reference in a new issue