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

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

This commit is contained in:
f 2024-06-19 18:22:31 -03:00
commit 258ec88318
No known key found for this signature in database
13 changed files with 135 additions and 48 deletions

View file

@ -11,6 +11,14 @@ $colors: (
"magenta": $magenta
);
// TODO: Encontrar la forma de generar esto desde los locales de Rails
$custom-file-text: (
en: "Browse",
es: "Buscar archivo",
pt: "Buscar arquivo",
pt-BR: "Buscar arquivo"
);
// Redefinir variables de Bootstrap
$primary: $magenta;
$secondary: $black;
@ -30,6 +38,8 @@ $input-bg: var(--background);
$input-color: var(--foreground);
$btn-bg-color: var(--btn-bg-color);
$btn-color: var(--btn-color);
$input-group-addon-bg: var(--btn-bg-color);
$custom-file-color: var(--btn-color);
$spacers: (
2-plus: 0.75rem
@ -101,12 +111,6 @@ $sizes: (
}
}
// TODO: Encontrar la forma de generar esto desde los locales de Rails
$custom-file-text: (
en: 'Browse',
es: 'Buscar archivo'
);
@font-face {
font-family: 'Saira';
font-style: normal;

View file

@ -128,7 +128,9 @@ class PostsController < ApplicationController
# condiciones.
if htmx?
if post.persisted?
swap_modals
triggers = { 'notification:show' => { 'id' => params.permit(:saved).values.first } }
swap_modals(triggers)
@value = post.title.value
@uuid = post.uuid.value
@ -169,7 +171,9 @@ class PostsController < ApplicationController
if htmx?
if post.persisted?
swap_modals
triggers = { 'notification:show' => params.permit(:saved).values.first }
swap_modals(triggers)
@value = post.title.value
@uuid = post.uuid.value

View file

@ -3,6 +3,16 @@ import { Controller } from "stimulus";
export default class extends Controller {
static targets = ["invalid", "submitting"];
// @todo Stimulus >1
get submittingIdValue() {
return this.element.dataset?.formValidationSubmittingIdValue;
}
// @todo Stimulus >1
get invalidIdValue() {
return this.element.dataset?.formValidationInvalidIdValue;
}
connect() {
this.element.setAttribute("novalidate", true);
@ -19,34 +29,19 @@ export default class extends Controller {
submit(event = undefined) {
event?.preventDefault();
event?.stopPropagation();
if (this.element.reportValidity()) {
this.element.classList.remove("was-validated");
this.element.submit();
this.show(this.submittingTargets);
this.hide(this.invalidTargets);
if (!this.element.hasAttribute("hx-post")) this.element.submit();
window.dispatchEvent(new CustomEvent("notification:show", { detail: { id: this.submittingIdValue } }));
} else {
event?.stopPropagation();
this.element.classList.add("was-validated");
this.hide(this.submittingTargets);
this.show(this.invalidTargets);
}
}
show(elements) {
for (const element of elements) {
element.classList.remove("d-none");
setTimeout(() => element.classList.add("show"), 1);
}
}
hide(elements) {
for (const element of elements) {
element.classList.remove("show");
setTimeout(() => element.classList.add("d-none"), 2000);
window.dispatchEvent(new CustomEvent("notification:show", { detail: { id: this.invalidIdValue } }));
}
}
}

View file

@ -0,0 +1,43 @@
import { Controller } from "stimulus";
/*
* Solo se puede mostrar una notificación a la vez
*/
export default class extends Controller {
// @todo Stimulus >1
get showClasses() {
return (this.element.dataset?.notificationShowClass || "").split(" ").filter(x => x);
}
// @todo Stimulus >1
get hideClasses() {
return (this.element.dataset?.notificationHideClass || "").split(" ").filter(x => x);
}
/*
* Al recibir el evento de mostrar, si no está dirigido al elemento
* actual, se oculta.
*/
show(event = undefined) {
if (event?.detail?.id !== this.element.id) {
this.hide({ detail: { id: this.element.id } });
return;
}
this.element.classList.remove("d-none");
setTimeout(() => {
this.element.classList.remove(...this.hideClasses);
this.element.classList.add(...this.showClasses);
}, 1);
}
hide(event = undefined) {
if (event?.detail?.id !== this.element.id) return;
this.element.classList.remove(...this.showClasses);
this.element.classList.add(...this.hideClasses);
setTimeout(() => this.element.classList.add("d-none"), 150);
}
}

View file

@ -31,11 +31,19 @@
end
- dir = t("locales.#{@locale}.dir")
- submitting_id = random_id
- invalid_id = random_id
- data = {}
- data[:controller] = 'unsaved-changes form-validation'
- data[:action] = 'unsaved-changes#submit form-validation#submit beforeunload@window->unsaved-changes#unsaved turbolinks:before-visit@window->unsaved-changes#unsavedTurbolinks'
- data[:'unsaved-changes-confirm-value'] = t('.confirm')
- data[:'form-validation-submitting-id-value'] = submitting_id
- data[:'form-validation-invalid-id-value'] = invalid_id
-# Comienza el formulario
= form_tag url, method: method, class: "form post #{extra_class}", multipart: true, data: { controller: 'unsaved-changes form-validation', action: 'unsaved-changes#submit form-validation#submit beforeunload@window->unsaved-changes#unsaved turbolinks:before-visit@window->unsaved-changes#unsavedTurbolinks', 'unsaved-changes-confirm-value': t('.confirm') } do
= form_tag url, method: method, class: "form post #{extra_class}", multipart: true, data: data do
-# Botones de guardado
= render 'posts/submit', site: site, post: post
= render 'posts/submit', site: site, post: post, invalid: invalid_id, submitting: submitting_id
= hidden_field_tag 'post[layout]', post.layout.name
@ -43,7 +51,7 @@
= render 'posts/attributes', site: site, post: post, dir: dir, base: 'post', locale: @locale
-# Botones de guardado
= render 'posts/submit', site: site, post: post
= render 'posts/submit', site: site, post: post, invalid: invalid_id, submitting: submitting_id
-# Formularios usados por los modales
= yield(:post_form)

View file

@ -27,7 +27,14 @@
multipart: true,
class: 'form post ',
'hx-swap': params.require(:swap),
'hx-target': "##{params.require(:target)}"
'hx-target': "##{params.require(:target)}",
'hx-validate': true,
data: {
controller: 'form-validation',
action: 'form-validation#submit',
'form-validation-submitting-id-value': params.permit(:submitting).values.first,
'form-validation-invalid-id-value': params.permit(:invalid).values.first,
}
}
if post.new?
@ -73,6 +80,8 @@
%input{ type: 'hidden', name: 'swap', value: params.require(:swap) }
- if params[:inverse].present?
%input{ type: 'hidden', name: 'inverse', value: params.require(:inverse) }
- if params[:saved].present?
%input{ type: 'hidden', name: 'saved', value: params.require(:saved) }
= hidden_field_tag "#{base}[layout]", post.layout.name

View file

@ -1,11 +1,3 @@
- invalid_help = site.config.fetch('invalid_help', t('.invalid_help'))
- submitting_help = site.config.fetch('submitting_help', t('.submitting_help'))
.d-flex.flex-column.flex-md-row.align-items-start.mb-3
%div
= submit_tag t('.save'), class: 'btn btn-secondary submit-post'
.d-flex.flex-column.position-relative
= render 'bootstrap/alert', class: 'm-0 d-none fade', data: { target: 'form-validation.invalid' } do
= invalid_help
= render 'bootstrap/alert', class: 'm-0 d-none fade position-absolute top-0 left-0', data: { target: 'form-validation.submitting' } do
= submitting_help
%div= submit_tag t('.save'), class: 'btn btn-secondary submit-post'
= render 'posts/validation', site: site, submitting: { id: submitting }, invalid: { id: invalid }

View file

@ -0,0 +1,16 @@
- invalid = site.config.fetch('invalid', t('.invalid'))
- submitting = site.config.fetch('submitting', t('.submitting'))
- %i[invalid submitting].each do |key|
- local_assigns[key] ||= {}
- local_assigns[key][:data] ||= {}
- local_assigns[key][:data][:target] ||= "form-validation.#{key}"
- local_assigns[key][:data][:action] ||= 'notification:show@window->notification#show'
- local_assigns[key][:data][:controller] ||= 'notification'
- local_assigns[key][:data][:'notification-hide-class'] ||= 'hide'
- local_assigns[key][:data][:'notification-show-class'] ||= 'show'
.d-flex.flex-column
= render 'bootstrap/alert', class: 'm-0 d-none fade', **local_assigns[:invalid] do
= invalid
= render 'bootstrap/alert', class: 'm-0 d-none fade', **local_assigns[:submitting] do
= submitting

View file

@ -27,6 +27,7 @@
= file_field(*field_name_for(base, attribute, :path),
**field_options(attribute, metadata, required: (metadata.required && !metadata.path?)),
class: "custom-file-input #{invalid(post, attribute)}",
lang: locale,
data: { target: 'file-preview.input', action: 'file-preview#update' })
= label_tag "#{base}_#{attribute}_path",
post_label_t(attribute, :path, post: post), class: 'custom-file-label'

View file

@ -24,6 +24,7 @@
**field_options(attribute, metadata, required: (metadata.required && !metadata.path?)),
class: "custom-file-input #{invalid(post, attribute)}",
accept: ActiveStorage.web_image_content_types.join(','),
lang: locale,
data: { target: 'file-preview.input', action: 'file-preview#update' })
= label_tag "#{base}_#{attribute}_path",
post_label_t(attribute, :path, post: post), class: 'custom-file-label'

View file

@ -19,6 +19,9 @@
post_form_loaded_id = random_id
value_list_id = random_id
layout = metadata.filter[:layout]
invalid_id = random_id
submitting_id = random_id
saved_id = random_id
%div{ data: { controller: 'modal' }}
.form-group
@ -43,10 +46,13 @@
= 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' }
.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, invalid: invalid_id, submitting: submitting_id, saved: saved_id), 'hx-trigger': 'load' }
%span.placeholder.w-100.h-100
- content_for :"#{id}_footer" do
= render 'posts/validation', site: site, invalid: { id: invalid_id }, submitting: { id: submitting_id }
= render 'bootstrap/alert', class: 'm-0 d-none fade', id: saved_id, data: { controller: 'notification', action: 'notification:show@window->notification#show', 'notification-hide-class': 'hide', 'notification-show-class': 'show' } do
= t('.saved')
= render 'bootstrap/btn', form: form_id, content: t('.save'), type: 'submit', class: 'm-0 mt-1 mr-1'
= render 'bootstrap/btn', content: t('.close'), action: 'modal#hide', class: 'm-0 mt-1 mr-1'

View file

@ -715,8 +715,9 @@ en:
submit:
save: 'Save'
save_draft: 'Save as draft'
invalid_help: "Some fields need attention! Please search for the fields marked as not valid."
submitting_help: "Saving changes, please wait..."
validation:
invalid: "Some fields need attention! Please search for the fields marked as not valid."
submitting: "Saving changes, please wait..."
new_array:
remove: "Remove"
attributes:
@ -966,3 +967,5 @@ en:
save: "Save"
card:
edit: "Edit"
alert:
saved: "Changes were saved!"

View file

@ -723,8 +723,9 @@ es:
submit:
save: 'Guardar'
save_draft: 'Guardar como borrador'
invalid_help: "¡Te falta completar algunos campos! Busca los que estén marcados como no válidos."
submitting_help: "Guardando, por favor espera..."
validation:
invalid: "¡Te falta completar algunos campos! Busca los que estén marcados como no válidos."
submitting: "Guardando, por favor espera..."
new_array:
remove: "Eliminar"
attributes:
@ -772,6 +773,8 @@ es:
edit: "Editar"
new_predefined_array:
edit: "Editar"
new_predefined_value:
edit: "Editar"
new_array:
edit: "Editar"
required: "Seleccioná al menos una opción."
@ -974,3 +977,5 @@ es:
save: "Guardar"
card:
edit: "Editar"
alert:
saved: "¡Cambios guardados!"