5
0
Fork 0
mirror of https://0xacab.org/sutty/sutty synced 2025-03-14 23:08:17 +00:00

Merge branch 'issue-15068' into production.panel.sutty.nl

This commit is contained in:
f 2024-06-03 17:53:54 -03:00
commit 9e5bfed017
No known key found for this signature in database
28 changed files with 203 additions and 61 deletions

View file

@ -86,7 +86,6 @@ gem 'rubanok'
gem 'after_commit_everywhere', '~> 1.0' gem 'after_commit_everywhere', '~> 1.0'
gem 'aasm' gem 'aasm'
gem 'que-web' gem 'que-web'
gem 'nanoid'
# database # database
gem 'hairtrigger' gem 'hairtrigger'

View file

@ -377,7 +377,6 @@ GEM
multi_xml (0.6.0) multi_xml (0.6.0)
mustermann (3.0.0) mustermann (3.0.0)
ruby2_keywords (~> 0.0.1) ruby2_keywords (~> 0.0.1)
nanoid (2.0.0)
net-imap (0.4.9) net-imap (0.4.9)
date date
net-protocol net-protocol
@ -683,7 +682,6 @@ DEPENDENCIES
memory_profiler memory_profiler
mini_magick mini_magick
mobility mobility
nanoid
net-ssh net-ssh
nokogiri nokogiri
pg pg

View file

@ -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

View file

@ -3,6 +3,17 @@
# Helpers # Helpers
module ApplicationHelper module ApplicationHelper
BRACKETS = /[\[\]]/.freeze BRACKETS = /[\[\]]/.freeze
ALPHA_LARGE = [*'a'..'z', *'A'..'Z'].freeze
# Devuelve un indentificador aleatorio que puede usarse como atributo
# HTML. Reemplaza Nanoid. El primer caracter siempre es alfabético.
#
# @return [String]
def random_id
SecureRandom.urlsafe_base64.tap do |s|
s[0] = ALPHA_LARGE.sample
end
end
# Devuelve el atributo name de un campo anidado en el formato que # Devuelve el atributo name de un campo anidado en el formato que
# esperan los helpers *_field # esperan los helpers *_field

View file

@ -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();

View file

@ -0,0 +1,27 @@
# frozen_string_literal: true
module Metadata
# Hasta ahora veníamos habilitando la opción de romper
# retroactivamente relaciones, sin informar que estaba sucediendo.
# Con este módulo, todas las relaciones que ya tienen una relación
# inversa son ignoradas.
module UnusedValuesConcern
extend ActiveSupport::Concern
included do
# Genera un Hash de { title | slug => uuid }, excluyendo el Post
# actual y todos los que ya tengan una relación inversa, para no
# romperla.
#
# @return [Hash]
def values
@values ||= posts.map do |p|
next if p.uuid.value == post.uuid.value
next unless inverse? && (p[inverse].empty? || [p[inverse].value].flatten.include?(post.uuid.value))
[title(p), p.uuid.value]
end.compact.to_h
end
end
end
end

View file

@ -1,4 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
# Nueva interfaz # Nueva interfaz
class MetadataNewBelongsTo < MetadataBelongsTo; end class MetadataNewBelongsTo < MetadataBelongsTo
include Metadata::UnusedValuesConcern
end

View file

@ -1,4 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
# Interfaz nueva para uno a muchos # Interfaz nueva para uno a muchos
class MetadataNewHasMany < MetadataHasMany; end class MetadataNewHasMany < MetadataHasMany
include Metadata::UnusedValuesConcern
end

View file

@ -0,0 +1,6 @@
# frozen_string_literal: true
# Nueva interfaz para relaciones 1:1
class MetadataNewHasOne < MetadataHasOne
include Metadata::UnusedValuesConcern
end

View file

@ -28,7 +28,7 @@
.modal.fade{ tabindex: -1, aria: { hidden: 'true' }, data: { target: 'modal.modal' } } .modal.fade{ tabindex: -1, aria: { hidden: 'true' }, data: { target: 'modal.modal' } }
.modal-backdrop.fade{ data: { target: 'modal.backdrop', action: local_assigns[:hide_actions].join(' ') } } .modal-backdrop.fade{ data: { target: 'modal.backdrop', action: local_assigns[:hide_actions].join(' ') } }
.modal-dialog.modal-dialog-scrollable.modal-dialog-centered .modal-dialog.modal-dialog-scrollable.modal-dialog-centered.modal-lg
.modal-content{ **local_assigns[:modal_content_attributes] } .modal-content{ **local_assigns[:modal_content_attributes] }
- if (header = yield(:"#{id}_header")).present? - if (header = yield(:"#{id}_header")).present?
.modal-header= header .modal-header= header

View file

@ -5,6 +5,16 @@
@param :post [Post] @param :post [Post]
@param :locale [Symbol, String] @param :locale [Symbol, String]
@param :dir [Symbol, String] @param :dir [Symbol, String]
@param [ActionController::StrongParameters] params
@option params [String] :inverse La relación inversa (opcional)
@option params [String] :form El ID del formulario actual, si tiene botones externos, tiene que estar compartido
@option params [String] :swap Método de intercambio del resultado (HTMX)
@option params [String] :target Elemento donde se carga el resultado (HTMX)
@option params [String] :hide ID del modal a esconder vía evento
@option params [String] :show ID del modal a mostrar vía evento
@option params [String] :base La base del formulario, que luego se envía como parámetro a PostService
@option params [String] :attribute El tipo de atributo, para saber qué respuesta generar
:ruby :ruby
except = %i[date] except = %i[date]
@ -51,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] }

View file

@ -0,0 +1,2 @@
= render 'posts/new_related_post', post: post
%input{ type: 'hidden', name: name, value: value }

View 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)

View file

@ -1,5 +1,5 @@
.form-check .form-check
= hidden_field_tag "#{base}[#{attribute}]", '0', id: '' = hidden_field_tag "#{base}[#{attribute}]", '0', id: nil
.custom-control.custom-switch .custom-control.custom-switch
= check_box_tag "#{base}[#{attribute}]", '1', metadata.value, = check_box_tag "#{base}[#{attribute}]", '1', metadata.value,
class: "custom-control-input #{invalid(post, attribute)}", class: "custom-control-input #{invalid(post, attribute)}",

View file

@ -3,7 +3,7 @@
:ruby :ruby
id = id_for(base, attribute) id = id_for(base, attribute)
name = "#{base}[#{attribute}][]" name = "#{base}[#{attribute}][]"
form_id = "form-#{Nanoid.generate}" form_id = random_id
%div{ data: { controller: 'modal array enter', 'array-original-value': metadata.value.to_json, 'array-new-array-value': site_posts_new_array_value_path(site) } } %div{ data: { controller: 'modal array enter', 'array-original-value': metadata.value.to_json, 'array-new-array-value': site_posts_new_array_value_path(site) } }
%template{ data: { target: 'array.placeholder' } } %template{ data: { target: 'array.placeholder' } }
@ -41,7 +41,7 @@
-# Eliminamos las tildes para poder buscar independientemente de cómo se escriba -# Eliminamos las tildes para poder buscar independientemente de cómo se escriba
- metadata.values.sort_by(&:remove_diacritics).each do |value| - metadata.values.sort_by(&:remove_diacritics).each do |value|
.mb-2{ data: { target: 'array.item', 'searchable-value': value.remove_diacritics.downcase, value: value } } .mb-2{ data: { target: 'array.item', 'searchable-value': value.remove_diacritics.downcase, value: value } }
= render 'bootstrap/custom_checkbox', name: name, id: "value-#{Nanoid.generate}", value: value, checked: metadata.value.include?(value), content: value = render 'bootstrap/custom_checkbox', name: name, id: random_id, value: value, checked: metadata.value.include?(value), content: value
- content_for :"#{id}_footer" do - content_for :"#{id}_footer" do
.input-group.w-auto.flex-grow-1.my-0 .input-group.w-auto.flex-grow-1.my-0

View file

@ -8,15 +8,15 @@
del formulario principal porque no se pueden anidar. del formulario principal porque no se pueden anidar.
:ruby :ruby
id = id_for(base, attribute) id = random_id
name = "#{base}[#{attribute}]" name = "#{base}[#{attribute}]"
form_id = "form-#{Nanoid.generate}" form_id = random_id
modal_id = "modal-#{Nanoid.generate}" modal_id = random_id
post_id = "post-#{Nanoid.generate}" post_id = random_id
post_form_id = "post-form-#{Nanoid.generate}" post_form_id = random_id
post_modal_id = "post-modal-#{Nanoid.generate}" post_modal_id = random_id
post_form_loaded_id = "post-loaded-#{Nanoid.generate}" post_form_loaded_id = random_id
value_list_id = "#{id}_body" value_list_id = random_id
%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) } } %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) } }
%template{ data: { target: 'array.placeholder' } } %template{ data: { target: 'array.placeholder' } }
@ -55,7 +55,7 @@
.form-group.mb-0{ id: value_list_id } .form-group.mb-0{ id: value_list_id }
- metadata.values.each_pair do |value, uuid| - metadata.values.each_pair do |value, uuid|
.mb-2{ data: { target: 'array.item', 'searchable-value': value.remove_diacritics.downcase, 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, type: 'radio' = render 'bootstrap/custom_checkbox', name: name, id: random_id, value: uuid, checked: metadata.value.include?(uuid), content: value, type: 'radio'
-# -#
Según la definición del campo, si hay un filtro, tenemos que poder Según la definición del campo, si hay un filtro, tenemos que poder

View file

@ -8,15 +8,15 @@
del formulario principal porque no se pueden anidar. del formulario principal porque no se pueden anidar.
:ruby :ruby
id = id_for(base, attribute) id = random_id
name = "#{base}[#{attribute}][]" name = "#{base}[#{attribute}][]"
form_id = "form-#{Nanoid.generate}" form_id = random_id
modal_id = "modal-#{Nanoid.generate}" modal_id = random_id
post_id = "post-#{Nanoid.generate}" post_id = random_id
post_form_id = "post-form-#{Nanoid.generate}" post_form_id = random_id
post_modal_id = "post-modal-#{Nanoid.generate}" post_modal_id = random_id
post_form_loaded_id = "post-loaded-#{Nanoid.generate}" post_form_loaded_id = random_id
value_list_id = "#{id}_body" value_list_id = random_id
%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) } } %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) } }
%template{ data: { target: 'array.placeholder' } } %template{ data: { target: 'array.placeholder' } }
@ -55,7 +55,7 @@
.form-group.mb-0{ id: value_list_id } .form-group.mb-0{ id: value_list_id }
- metadata.values.each_pair do |value, uuid| - metadata.values.each_pair do |value, uuid|
.mb-2{ data: { target: 'array.item', 'searchable-value': value.remove_diacritics.downcase, 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 = render 'bootstrap/custom_checkbox', name: name, id: random_id, value: uuid, checked: metadata.value.include?(uuid), content: value
-# -#
Según la definición del campo, si hay un filtro, tenemos que poder Según la definición del campo, si hay un filtro, tenemos que poder

View file

@ -10,13 +10,13 @@
:ruby :ruby
id = id_for(base, attribute) id = id_for(base, attribute)
name = "#{base}[#{attribute}][]" name = "#{base}[#{attribute}][]"
form_id = "form-#{Nanoid.generate}" form_id = random_id
modal_id = "modal-#{Nanoid.generate}" modal_id = random_id
post_id = "post-#{Nanoid.generate}" post_id = random_id
post_form_id = "post-form-#{Nanoid.generate}" post_form_id = random_id
post_modal_id = "post-modal-#{Nanoid.generate}" post_modal_id = random_id
post_form_loaded_id = "post-loaded-#{Nanoid.generate}" post_form_loaded_id = random_id
value_list_id = "#{id}_body" value_list_id = random_id
%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) } } %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) } }
%template{ data: { target: 'array.placeholder' } } %template{ data: { target: 'array.placeholder' } }
@ -55,7 +55,7 @@
.form-group.mb-0{ id: value_list_id } .form-group.mb-0{ id: value_list_id }
- metadata.values.each_pair do |value, uuid| - metadata.values.each_pair do |value, uuid|
.mb-2{ data: { target: 'array.item', 'searchable-value': value.remove_diacritics.downcase, 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 = render 'bootstrap/custom_checkbox', name: name, id: random_id, value: uuid, checked: metadata.value.include?(uuid), content: value
-# -#
Según la definición del campo, si hay un filtro, tenemos que poder Según la definición del campo, si hay un filtro, tenemos que poder

View 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

View file

@ -5,7 +5,7 @@
:ruby :ruby
id = id_for(base, attribute) id = id_for(base, attribute)
name = "#{base}[#{attribute}][]" name = "#{base}[#{attribute}][]"
form_id = "form-#{Nanoid.generate}" form_id = random_id
%div{ data: { controller: 'modal array', 'array-original-value': metadata.value.to_json, 'array-new-array-value': site_posts_new_array_value_path(site) } } %div{ data: { controller: 'modal array', 'array-original-value': metadata.value.to_json, 'array-new-array-value': site_posts_new_array_value_path(site) } }
%template{ data: { target: 'array.placeholder' } } %template{ data: { target: 'array.placeholder' } }
@ -44,7 +44,7 @@
-# Eliminamos las tildes para poder buscar independientemente de cómo se escriba -# Eliminamos las tildes para poder buscar independientemente de cómo se escriba
- metadata.values.each_pair do |value, key| - metadata.values.each_pair do |value, key|
.mb-2{ data: { target: 'array.item', 'searchable-value': value.remove_diacritics.downcase, value: value } } .mb-2{ data: { target: 'array.item', 'searchable-value': value.remove_diacritics.downcase, value: value } }
= render 'bootstrap/custom_checkbox', name: name, id: "value-#{Nanoid.generate}", value: key, checked: metadata.value.include?(key), content: value = render 'bootstrap/custom_checkbox', name: name, id: random_id, value: key, checked: metadata.value.include?(key), content: value
- content_for :"#{id}_footer" do - content_for :"#{id}_footer" do
-# Alinear los botones a la derecha -# Alinear los botones a la derecha

View file

@ -10,13 +10,13 @@
:ruby :ruby
id = id_for(base, attribute) id = id_for(base, attribute)
name = "#{base}[#{attribute}]" name = "#{base}[#{attribute}]"
form_id = "form-#{Nanoid.generate}" form_id = random_id
modal_id = "modal-#{Nanoid.generate}" modal_id = random_id
post_id = "post-#{Nanoid.generate}" post_id = random_id
post_form_id = "post-form-#{Nanoid.generate}" post_form_id = random_id
post_modal_id = "post-modal-#{Nanoid.generate}" post_modal_id = random_id
post_form_loaded_id = "post-loaded-#{Nanoid.generate}" post_form_loaded_id = random_id
value_list_id = "#{id}_body" value_list_id = random_id
%div{ id: modal_id, data: { controller: 'modal array', 'array-original-value': metadata.value.to_json, 'array-new-array-value': site_posts_new_array_value_path(site) } } %div{ id: modal_id, data: { controller: 'modal array', 'array-original-value': metadata.value.to_json, 'array-new-array-value': site_posts_new_array_value_path(site) } }
%template{ data: { target: 'array.placeholder' } } %template{ data: { target: 'array.placeholder' } }
@ -54,7 +54,7 @@
.form-group.mb-0{ id: value_list_id } .form-group.mb-0{ id: value_list_id }
- metadata.values.each_pair do |value, key| - metadata.values.each_pair do |value, key|
.mb-2{ data: { target: 'array.item', 'searchable-value': value.remove_diacritics.downcase, value: value } } .mb-2{ data: { target: 'array.item', 'searchable-value': value.remove_diacritics.downcase, value: value } }
= render 'bootstrap/custom_checkbox', name: name, id: "value-#{Nanoid.generate}", value: key, checked: (metadata.value == key), content: value, type: 'radio' = render 'bootstrap/custom_checkbox', name: name, id: random_id, value: key, checked: (metadata.value == key), content: value, type: 'radio'
- content_for :"#{id}_footer" do - content_for :"#{id}_footer" do
= render 'bootstrap/btn', content: t('.accept'), action: 'array#accept modal#hide', class: 'm-0 mr-1' = render 'bootstrap/btn', content: t('.accept'), action: 'array#accept modal#hide', class: 'm-0 mr-1'

View file

@ -1 +1 @@
-# nada = hidden_field_tag "#{base}[#{attribute}]", metadata.value

View file

@ -1,8 +1,8 @@
- item_id = "item-#{Nanoid.generate}" - item_id = random_id
.mb-2{ id: item_id, data: { target: 'array.item', 'searchable-value': @value.remove_diacritics.downcase, value: @value } } .mb-2{ id: item_id, data: { target: 'array.item', 'searchable-value': @value.remove_diacritics.downcase, value: @value } }
.d-flex.flex-row.flex-wrap .d-flex.flex-row.flex-wrap
.flex-grow-1 .flex-grow-1
= render 'bootstrap/custom_checkbox', name: @name, id: "value-#{Nanoid.generate}", value: @value, checked: true, content: @value = render 'bootstrap/custom_checkbox', name: @name, id: random_id, value: @value, checked: true, content: @value
%div %div
%button.btn.btn-sm.m-0{ data: { action: 'array#remove', 'remove-target-param': item_id } }= t('.remove') %button.btn.btn-sm.m-0{ data: { action: 'array#remove', 'remove-target-param': item_id } }= t('.remove')

View file

@ -1,2 +1,2 @@
.mb-2{ data: { target: 'array.item', 'searchable-value': @value.remove_diacritics.downcase, 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: true, content: @value, type: 'radio' = render 'bootstrap/custom_checkbox', name: @name, id: random_id, value: @uuid, checked: true, content: @value, type: 'radio'

View file

@ -1,2 +1,2 @@
.mb-2{ data: { target: 'array.item', 'searchable-value': @value.remove_diacritics.downcase, 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: true, content: @value = render 'bootstrap/custom_checkbox', name: @name, id: random_id, value: @uuid, checked: true, content: @value

View file

@ -0,0 +1 @@
= render 'posts/new_has_one', post: @indexed_post, name: params.require(:name), value: @uuid

View file

@ -0,0 +1 @@
= render 'posts/new_has_one', post: @post.to_index, name: params.require(:name), value: @uuid

View file

@ -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