pg_rails 7.6.2 → 7.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/pg_associable/app/helpers/pg_associable/form_builder_methods.rb +3 -0
- data/pg_engine/app/assets/stylesheets/pg_rails_b5.scss +29 -3
- data/pg_engine/app/components/bad_user_input_component.rb +1 -0
- data/pg_engine/app/components/inline_edit/inline_component.rb +27 -0
- data/pg_engine/app/components/inline_edit/inline_edit_component.html.slim +14 -0
- data/pg_engine/app/components/inline_edit/inline_edit_component.rb +13 -0
- data/pg_engine/app/components/inline_edit/inline_show_component.html.slim +8 -0
- data/pg_engine/app/components/inline_edit/inline_show_component.rb +2 -0
- data/pg_engine/app/controllers/concerns/pg_engine/resource.rb +8 -4
- data/pg_engine/app/controllers/pg_engine/base_controller.rb +7 -16
- data/pg_engine/app/controllers/users/inline_edit_controller.rb +21 -0
- data/pg_engine/app/decorators/pg_engine/base_record_decorator.rb +2 -2
- data/pg_engine/app/helpers/pg_engine/index_helper.rb +1 -1
- data/pg_engine/app/lib/pg_form_builder.rb +18 -0
- data/pg_engine/app/models/pg_engine/base_record.rb +5 -1
- data/pg_engine/app/views/pg_engine/base/index.html.slim +2 -1
- data/pg_engine/config/initializers/zeitwerk.rb +2 -0
- data/pg_engine/config/routes.rb +4 -0
- data/pg_engine/config/simple_form/simple_form_bootstrap.rb +32 -2
- data/pg_engine/spec/controllers/pg_engine/base_controller_spec.rb +1 -16
- data/pg_engine/spec/requests/users/accounts_spec.rb +1 -2
- data/pg_engine/spec/requests/users/inline_edit_spec.rb +101 -0
- data/pg_layout/app/javascript/config/index.js +20 -20
- data/pg_layout/app/javascript/config/turbo_rails/index.js +4 -2
- data/pg_rails/lib/version.rb +1 -1
- data/pg_rails/scss/pg_rails.scss +4 -4
- data/pg_scaffold/lib/generators/pg_active_record/model/templates/model.rb +3 -0
- data/pg_scaffold/lib/generators/pg_slim/templates/_form.html.slim +1 -1
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 558b69c5a93797c069002f3477d6ccc34b63b98fa4f1a37ddedcc4ab6010ef3b
|
4
|
+
data.tar.gz: a3cc4d53326372aaa5e7155b2d50cfdee3fc3d0814a81eee53ec3701814c3e23
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 259c3f0cc7c935f4a5b9569a2cd33cb1cc60e71a1c5cc85118fb3190415ebad4d78065c641bbe0bdaf479639df1be0ef93ded0ad589313f7dd23011ecfa618d8
|
7
|
+
data.tar.gz: b0e0ad29958f836916d4469d43bd5f3c8797eb9e00a981694034c025158083f28a0ea32bce7057a957bd2d2898d75daf7905fc9e0facd2ec78677f0de06c3389
|
@@ -41,6 +41,7 @@ module PgAssociable
|
|
41
41
|
user = Current.user
|
42
42
|
puede_crear = !template.using_modal? && Pundit::PolicyFinder.new(klass).policy.new(user, klass).new?
|
43
43
|
collection = Pundit::PolicyFinder.new(klass).scope.new(user, klass).resolve
|
44
|
+
collection = collection.kept if collection.respond_to?(:kept)
|
44
45
|
[collection, puede_crear]
|
45
46
|
end
|
46
47
|
|
@@ -50,9 +51,11 @@ module PgAssociable
|
|
50
51
|
options.deep_merge!({ wrapper_html: { 'data-preload': collection.decorate.to_json } })
|
51
52
|
end
|
52
53
|
# TODO: usar una clase más precisa para el modal?
|
54
|
+
# quizás sea este el motivo por el cual no funciona el multimodal
|
53
55
|
options.deep_merge!({ wrapper_html: { data: { controller: 'asociable',
|
54
56
|
'asociable-modal-outlet': '.modal' } } })
|
55
57
|
options[:as] = 'pg_associable'
|
58
|
+
|
56
59
|
association atributo, options
|
57
60
|
end
|
58
61
|
|
@@ -73,9 +73,10 @@ input[type=datetime-local], input[type=datetime] {
|
|
73
73
|
display: flex;
|
74
74
|
justify-content: flex-end;
|
75
75
|
gap: 4px;
|
76
|
-
|
77
|
-
.
|
78
|
-
|
76
|
+
|
77
|
+
.btn-sm {
|
78
|
+
padding: 0em 0.3em;
|
79
|
+
}
|
79
80
|
}
|
80
81
|
|
81
82
|
.list-group-item {
|
@@ -199,3 +200,28 @@ input[type=datetime-local], input[type=datetime] {
|
|
199
200
|
}
|
200
201
|
--fc-neutral-bg-color: none;
|
201
202
|
}
|
203
|
+
|
204
|
+
// Inline edit
|
205
|
+
|
206
|
+
.inline-edit {
|
207
|
+
// text-decoration: underline;
|
208
|
+
// text-decoration-style: dotted;
|
209
|
+
// text-decoration-color: #262626;
|
210
|
+
border-bottom: 1px dotted #333;
|
211
|
+
padding-bottom: 1px;
|
212
|
+
|
213
|
+
a:hover {
|
214
|
+
i {
|
215
|
+
color: black;
|
216
|
+
}
|
217
|
+
}
|
218
|
+
|
219
|
+
input[type=text] {
|
220
|
+
min-width: 22em;
|
221
|
+
}
|
222
|
+
|
223
|
+
// To display correctly in tables with fixed witdh columns
|
224
|
+
.form-select {
|
225
|
+
width: initial;
|
226
|
+
}
|
227
|
+
}
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class InlineComponent < ViewComponent::Base
|
2
|
+
def initialize(model, attribute)
|
3
|
+
@model = model
|
4
|
+
@attribute = attribute
|
5
|
+
@unsuffixed_attribute = unsuffixed(attribute)
|
6
|
+
@frame_id = dom_id(model, "#{attribute}_inline_edit")
|
7
|
+
|
8
|
+
super
|
9
|
+
end
|
10
|
+
|
11
|
+
def before_render
|
12
|
+
return unless controller.in_modal?
|
13
|
+
|
14
|
+
controller.instance_variable_set(:@using_modal, true)
|
15
|
+
end
|
16
|
+
|
17
|
+
SUFIJOS = %i[f text].freeze
|
18
|
+
def unsuffixed(attribute)
|
19
|
+
ret = attribute.to_s.dup
|
20
|
+
|
21
|
+
SUFIJOS.each do |sufijo|
|
22
|
+
ret.gsub!(/_#{sufijo}$/, '')
|
23
|
+
end
|
24
|
+
|
25
|
+
ret
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
= helpers.turbo_frame_tag(@frame_id, class: 'inline-edit')
|
2
|
+
= helpers.pg_form_for(@model, render_errors: false, wrapper_mappings: @wrapper_mappings,
|
3
|
+
html: { class: 'd-flex align-items-start gap-1' }) do |f|
|
4
|
+
= hidden_field_tag :inline_attribute, @attribute
|
5
|
+
|
6
|
+
= f.field @unsuffixed_attribute, label: false, html5: true
|
7
|
+
|
8
|
+
= button_tag class: 'btn btn-sm btn-primary',
|
9
|
+
data: { controller: 'tooltip', 'bs-title': 'Guardar' } do
|
10
|
+
i.bi.bi-check-lg
|
11
|
+
= link_to users_inline_show_path(model: @model.to_gid, attribute: @attribute),
|
12
|
+
class: 'btn btn-sm btn-secondary',
|
13
|
+
data: { controller: 'tooltip', 'bs-title': 'Cancelar' } do
|
14
|
+
i.bi.bi-x-lg
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class InlineEditComponent < InlineComponent
|
2
|
+
def initialize(*)
|
3
|
+
@wrapper_mappings = {
|
4
|
+
string: :inline_form_grow,
|
5
|
+
pg_associable: :inline_form_control,
|
6
|
+
date: :inline_form_control,
|
7
|
+
datetime: :inline_form_control,
|
8
|
+
select: :inline_form_select
|
9
|
+
}
|
10
|
+
|
11
|
+
super
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
- if @model.class.inline_editable?(@unsuffixed_attribute) && helpers.policy(@model).edit?
|
2
|
+
= helpers.turbo_frame_tag(@frame_id, class: 'inline-edit')
|
3
|
+
= link_to users_inline_edit_path(model: @model.to_gid, attribute: @attribute),
|
4
|
+
class: 'text-body-tertiary', style: 'font-size: 0.8em' do
|
5
|
+
i.bi.bi-pencil
|
6
|
+
span.ms-1 = @model.decorate.send(@attribute)
|
7
|
+
- else
|
8
|
+
= @model.decorate.send(@attribute)
|
@@ -257,7 +257,9 @@ module PgEngine
|
|
257
257
|
if (@saved = object.save)
|
258
258
|
respond_to do |format|
|
259
259
|
format.html do
|
260
|
-
if
|
260
|
+
if params[:inline_attribute].present?
|
261
|
+
render InlineShowComponent.new(object, params[:inline_attribute]), layout: false
|
262
|
+
elsif in_modal?
|
261
263
|
body = <<~HTML.html_safe
|
262
264
|
<pg-event data-event-name="pg:record-updated" data-turbo-temporary
|
263
265
|
data-response='#{object.decorate.to_json}'></pg-event>
|
@@ -272,6 +274,9 @@ module PgEngine
|
|
272
274
|
render json: object.decorate.as_json
|
273
275
|
end
|
274
276
|
end
|
277
|
+
elsif params[:inline_attribute].present?
|
278
|
+
render InlineEditComponent.new(object, params[:inline_attribute]),
|
279
|
+
layout: false, status: :unprocessable_entity
|
275
280
|
else
|
276
281
|
add_breadcrumb instancia_modelo.decorate.to_s_short, instancia_modelo.decorate.target_object
|
277
282
|
add_breadcrumb 'Modificando'
|
@@ -409,17 +414,16 @@ module PgEngine
|
|
409
414
|
def set_instancia_modelo
|
410
415
|
if action_name.in? %w[new create]
|
411
416
|
self.instancia_modelo = clase_modelo.new(modelo_params)
|
417
|
+
authorize(instancia_modelo)
|
412
418
|
if nested_id.present?
|
413
419
|
instancia_modelo.send("#{nested_key}=", nested_id)
|
414
420
|
end
|
415
421
|
else
|
416
422
|
self.instancia_modelo = buscar_instancia
|
417
|
-
|
423
|
+
authorize(instancia_modelo)
|
418
424
|
instancia_modelo.assign_attributes(modelo_params) if action_name.in? %w[update]
|
419
425
|
end
|
420
426
|
|
421
|
-
authorize(instancia_modelo)
|
422
|
-
|
423
427
|
# TODO: problema en create y update cuando falla la validacion
|
424
428
|
# Reproducir el error antes de arreglarlo
|
425
429
|
self.instancia_modelo = instancia_modelo.decorate if action_name.in? %w[show edit new]
|
@@ -216,22 +216,13 @@ module PgEngine
|
|
216
216
|
end
|
217
217
|
|
218
218
|
def not_authorized(_arg_required_for_active_admin)
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
if request.path == root_path
|
227
|
-
# TODO!: renderear un 500.html y pg_err
|
228
|
-
sign_out(Current.user) if Current.user.present?
|
229
|
-
render plain: 'Acceso no autorizado', status: :unprocessable_entity
|
230
|
-
else
|
231
|
-
go_back('Acceso no autorizado')
|
232
|
-
end
|
233
|
-
end
|
234
|
-
end
|
219
|
+
pg_warn <<~STRING
|
220
|
+
Acceso no autorizado.
|
221
|
+
User: #{Current.user.inspect}
|
222
|
+
Request: #{request.inspect}
|
223
|
+
STRING
|
224
|
+
|
225
|
+
render_my_component(BadUserInputComponent.new(error_msg: 'Acceso no autorizado'), :unauthorized)
|
235
226
|
end
|
236
227
|
|
237
228
|
def go_back(message = nil, type: :alert)
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Users
|
2
|
+
class InlineEditController < PgEngine.config.users_controller
|
3
|
+
before_action do
|
4
|
+
if current_turbo_frame.blank?
|
5
|
+
render_my_component(BadRequestComponent.new, :bad_request)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def edit
|
10
|
+
model = GlobalID::Locator.locate params[:model]
|
11
|
+
attribute = params[:attribute]
|
12
|
+
render InlineEditComponent.new(model, attribute), layout: false
|
13
|
+
end
|
14
|
+
|
15
|
+
def show
|
16
|
+
model = GlobalID::Locator.locate params[:model]
|
17
|
+
attribute = params[:attribute]
|
18
|
+
render InlineShowComponent.new(model, attribute), layout: false
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -26,6 +26,24 @@ class PgFormBuilder < SimpleForm::FormBuilder
|
|
26
26
|
super
|
27
27
|
end
|
28
28
|
|
29
|
+
def field(attribute_name, options = {}, &)
|
30
|
+
model = convert_to_model(object)
|
31
|
+
|
32
|
+
if find_on_all_associations(model.class, attribute_name).present?
|
33
|
+
pg_associable(attribute_name, options)
|
34
|
+
else
|
35
|
+
input(attribute_name, options, &)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def find_on_all_associations(klass, campo)
|
40
|
+
return unless klass.respond_to? :reflect_on_all_associations
|
41
|
+
|
42
|
+
klass.reflect_on_all_associations.find do |a|
|
43
|
+
a.name == campo.to_sym
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
29
47
|
def mensajes_de_error
|
30
48
|
# TODO: quitar en before-cache?
|
31
49
|
title = error_notification(message: mensaje, class: 'text-danger mb-2 error-title') if mensaje
|
@@ -16,7 +16,11 @@ module PgEngine
|
|
16
16
|
class << self
|
17
17
|
# This is a per class variable, all subclasses of BaseRecord inherit it
|
18
18
|
# BUT **the values are independent between all of them**
|
19
|
-
attr_accessor :default_modal
|
19
|
+
attr_accessor :default_modal, :inline_editable_fields
|
20
|
+
|
21
|
+
def inline_editable?(attribute)
|
22
|
+
inline_editable_fields.present? && inline_editable_fields.include?(attribute.to_sym)
|
23
|
+
end
|
20
24
|
end
|
21
25
|
|
22
26
|
# ransacker :search do |parent|
|
@@ -25,7 +25,8 @@ div
|
|
25
25
|
th.text-nowrap style="font-size: 0.8em" = encabezado att, ordenable: true
|
26
26
|
th.text-end
|
27
27
|
- unless @export_link == false
|
28
|
-
|
28
|
+
.actions-wrapper
|
29
|
+
= @clase_modelo.new.decorate.export_link(request.url)
|
29
30
|
tbody
|
30
31
|
- @collection.each do |object|
|
31
32
|
- object = object.decorate
|
data/pg_engine/config/routes.rb
CHANGED
@@ -21,6 +21,10 @@ Rails.application.routes.draw do
|
|
21
21
|
registrations: 'users/registrations'
|
22
22
|
}, failure_app: PgEngine::DeviseFailureApp
|
23
23
|
namespace :users, path: 'u' do
|
24
|
+
scope controller: 'inline_edit', path: 'inline', as: :inline do
|
25
|
+
get 'edit'
|
26
|
+
get 'show'
|
27
|
+
end
|
24
28
|
get 'dashboard', to: 'dashboard#dashboard'
|
25
29
|
post 'notifications/mark_as_seen', to: 'notifications#mark_as_seen'
|
26
30
|
post 'notifications/mark_as_unseen', to: 'notifications#mark_as_unseen'
|
@@ -270,7 +270,7 @@ SimpleForm.setup do |config|
|
|
270
270
|
# inline forms
|
271
271
|
#
|
272
272
|
# inline default_wrapper
|
273
|
-
config.wrappers :
|
273
|
+
config.wrappers :inline_form_grow, class: 'flex-grow-1' do |b|
|
274
274
|
b.use :html5
|
275
275
|
b.use :placeholder
|
276
276
|
b.optional :maxlength
|
@@ -280,7 +280,37 @@ SimpleForm.setup do |config|
|
|
280
280
|
b.optional :readonly
|
281
281
|
b.use :label, class: 'visually-hidden'
|
282
282
|
|
283
|
-
b.use :input, class: 'form-control', error_class: 'is-invalid'
|
283
|
+
b.use :input, class: 'form-control form-control-sm', error_class: 'is-invalid'
|
284
|
+
b.use :error, wrap_with: { class: 'invalid-feedback' }
|
285
|
+
b.optional :hint, wrap_with: { class: 'form-text' }
|
286
|
+
end
|
287
|
+
|
288
|
+
config.wrappers :inline_form_control, class: '' do |b|
|
289
|
+
b.use :html5
|
290
|
+
b.use :placeholder
|
291
|
+
b.optional :maxlength
|
292
|
+
b.optional :minlength
|
293
|
+
b.optional :pattern
|
294
|
+
b.optional :min_max
|
295
|
+
b.optional :readonly
|
296
|
+
b.use :label, class: 'visually-hidden'
|
297
|
+
|
298
|
+
b.use :input, class: 'form-control form-control-sm', error_class: 'is-invalid'
|
299
|
+
b.use :error, wrap_with: { class: 'invalid-feedback' }
|
300
|
+
b.optional :hint, wrap_with: { class: 'form-text' }
|
301
|
+
end
|
302
|
+
|
303
|
+
config.wrappers :inline_form_select, class: '' do |b|
|
304
|
+
b.use :html5
|
305
|
+
b.use :placeholder
|
306
|
+
b.optional :maxlength
|
307
|
+
b.optional :minlength
|
308
|
+
b.optional :pattern
|
309
|
+
b.optional :min_max
|
310
|
+
b.optional :readonly
|
311
|
+
b.use :label, class: 'visually-hidden'
|
312
|
+
|
313
|
+
b.use :input, class: 'form-select form-select-sm', error_class: 'is-invalid'
|
284
314
|
b.use :error, wrap_with: { class: 'invalid-feedback' }
|
285
315
|
b.optional :hint, wrap_with: { class: 'form-text' }
|
286
316
|
end
|
@@ -84,22 +84,7 @@ describe DummyBaseController do
|
|
84
84
|
|
85
85
|
it do
|
86
86
|
subject
|
87
|
-
expect(response).to
|
88
|
-
expect(flash[:alert]).to eq 'Acceso no autorizado'
|
89
|
-
expect(controller).to be_user_signed_in
|
90
|
-
end
|
91
|
-
|
92
|
-
context 'cuando ocurre en el root_path' do
|
93
|
-
before do
|
94
|
-
allow_any_instance_of(ActionController::TestRequest).to receive(:path).and_return(root_path)
|
95
|
-
end
|
96
|
-
|
97
|
-
it do
|
98
|
-
subject
|
99
|
-
expect(response).to have_http_status(:unprocessable_entity)
|
100
|
-
expect(response.body).to eq 'Acceso no autorizado'
|
101
|
-
expect(controller).not_to be_user_signed_in
|
102
|
-
end
|
87
|
+
expect(response).to have_http_status(:unauthorized)
|
103
88
|
end
|
104
89
|
end
|
105
90
|
|
@@ -16,7 +16,6 @@ describe 'Users::AccountsController' do
|
|
16
16
|
it 'denies foreign account' do
|
17
17
|
other_account = create :account
|
18
18
|
get "/u/cuentas/#{other_account.to_param}"
|
19
|
-
expect(response).to have_http_status(:
|
20
|
-
expect(flash[:alert]).to eq 'Acceso no autorizado'
|
19
|
+
expect(response).to have_http_status(:unauthorized)
|
21
20
|
end
|
22
21
|
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
describe 'inline edit' do
|
4
|
+
before do
|
5
|
+
user = create :user
|
6
|
+
sign_in user
|
7
|
+
end
|
8
|
+
|
9
|
+
let(:cosa) { create :cosa }
|
10
|
+
|
11
|
+
describe '#show' do
|
12
|
+
subject do
|
13
|
+
get '/u/inline/show', params:, headers: { 'Turbo-Frame': turbo_frame_id }
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:params) do
|
17
|
+
{ model: cosa.to_gid.to_param, attribute: :nombre }
|
18
|
+
end
|
19
|
+
|
20
|
+
let(:turbo_frame_id) { 'turbo-frame' }
|
21
|
+
|
22
|
+
it do
|
23
|
+
subject
|
24
|
+
expect(response).to have_http_status(:ok)
|
25
|
+
expect(response.body).to include cosa.nombre
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'when no turbo frame targetted' do
|
29
|
+
let(:turbo_frame_id) { nil }
|
30
|
+
|
31
|
+
it do
|
32
|
+
subject
|
33
|
+
expect(response).to have_http_status(:bad_request)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe '#edit' do
|
39
|
+
subject do
|
40
|
+
get '/u/inline/edit', params:, headers: { 'Turbo-Frame': turbo_frame_id }
|
41
|
+
end
|
42
|
+
|
43
|
+
let(:params) do
|
44
|
+
{ model: cosa.to_gid.to_param, attribute: :nombre }
|
45
|
+
end
|
46
|
+
|
47
|
+
let(:turbo_frame_id) { 'turbo-frame' }
|
48
|
+
|
49
|
+
it do
|
50
|
+
subject
|
51
|
+
expect(response).to have_http_status(:ok)
|
52
|
+
expect(response.body).to include cosa.nombre
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'when no turbo frame targetted' do
|
56
|
+
let(:turbo_frame_id) { nil }
|
57
|
+
|
58
|
+
it do
|
59
|
+
subject
|
60
|
+
expect(response).to have_http_status(:bad_request)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe '#update' do
|
66
|
+
subject do
|
67
|
+
patch "/u/cosas/#{cosa.to_param}", params:
|
68
|
+
end
|
69
|
+
|
70
|
+
let(:params) do
|
71
|
+
{
|
72
|
+
inline_attribute: 'nombre',
|
73
|
+
cosa: {
|
74
|
+
nombre:
|
75
|
+
}
|
76
|
+
}
|
77
|
+
end
|
78
|
+
|
79
|
+
let(:nombre) { 'otro' }
|
80
|
+
|
81
|
+
it do
|
82
|
+
subject
|
83
|
+
expect(response.body).to include 'turbo-frame'
|
84
|
+
expect(response).to have_http_status(:ok)
|
85
|
+
end
|
86
|
+
|
87
|
+
it do
|
88
|
+
expect { subject }.to change { cosa.reload.nombre }.to 'otro'
|
89
|
+
end
|
90
|
+
|
91
|
+
context 'when validation fails' do
|
92
|
+
let(:nombre) { nil }
|
93
|
+
|
94
|
+
it do
|
95
|
+
subject
|
96
|
+
expect(response.body).to include 'turbo-frame'
|
97
|
+
expect(response).to have_http_status(:unprocessable_entity)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -7,23 +7,23 @@ import './tooltips'
|
|
7
7
|
import 'trix'
|
8
8
|
import '@rails/actiontext'
|
9
9
|
|
10
|
-
function bindListingClick () {
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
}
|
27
|
-
bindListingClick()
|
28
|
-
document.addEventListener('turbo:load', bindListingClick)
|
29
|
-
document.addEventListener('turbo:render', bindListingClick)
|
10
|
+
// function bindListingClick () {
|
11
|
+
// document.body.onclick = (ev) => {
|
12
|
+
// if (ev.target.closest('a')) return
|
13
|
+
// if (ev.target.closest('.listado')) {
|
14
|
+
// const row = ev.target.closest('tr')
|
15
|
+
// if (row) {
|
16
|
+
// const show = row.querySelector('.bi-eye-fill')
|
17
|
+
// if (show) {
|
18
|
+
// const link = show.closest('a')
|
19
|
+
// if (link) {
|
20
|
+
// link.click()
|
21
|
+
// }
|
22
|
+
// }
|
23
|
+
// }
|
24
|
+
// }
|
25
|
+
// }
|
26
|
+
// }
|
27
|
+
// bindListingClick()
|
28
|
+
// document.addEventListener('turbo:load', bindListingClick)
|
29
|
+
// document.addEventListener('turbo:render', bindListingClick)
|
@@ -23,8 +23,10 @@ document.addEventListener('turbo:before-cache', () => {
|
|
23
23
|
})
|
24
24
|
})
|
25
25
|
|
26
|
-
document.addEventListener('turbo:frame-missing', (ev) => {
|
27
|
-
|
26
|
+
document.addEventListener('turbo:frame-missing', async (ev) => {
|
27
|
+
const text = await ev.detail.response.text()
|
28
|
+
Rollbar.error('turbo:frame-missing', text, ev.detail)
|
29
|
+
console.error('turbo:frame-missing', text, ev.detail)
|
28
30
|
ev.preventDefault()
|
29
31
|
const html = `
|
30
32
|
<div>
|
data/pg_rails/lib/version.rb
CHANGED
data/pg_rails/scss/pg_rails.scss
CHANGED
@@ -89,7 +89,7 @@ $light-border-emphasis: shade-color($light, 60%);
|
|
89
89
|
border: 1px solid $light-border-emphasis;
|
90
90
|
}
|
91
91
|
|
92
|
-
.listado tr:has(td:hover):has(.bi-eye-fill) td {
|
93
|
-
|
94
|
-
|
95
|
-
}
|
92
|
+
// .listado tr:has(td:hover):has(.bi-eye-fill) td {
|
93
|
+
// background-color: #f2f2f2;
|
94
|
+
// cursor: pointer;
|
95
|
+
// }
|
@@ -15,6 +15,9 @@ class <%= class_name %> < <%= parent_class_name.classify %>
|
|
15
15
|
<%- if options[:discard] -%>
|
16
16
|
include Discard::Model
|
17
17
|
<%- end -%>
|
18
|
+
|
19
|
+
self.default_modal = true
|
20
|
+
self.inline_editable_fields = %i[<%= attributes.map(&:name).join(' ') %>]
|
18
21
|
<%- if attributes.any?(&:reference?) -%>
|
19
22
|
|
20
23
|
<%- attributes.select(&:reference?).each do |attribute| -%>
|
@@ -3,7 +3,7 @@
|
|
3
3
|
div style="max-width: 22em" data-controller="pg_form"
|
4
4
|
= pg_form_for(@<%= singular_name %> || object) do |f|
|
5
5
|
<%- attributes.each do |attribute| -%>
|
6
|
-
= f
|
6
|
+
= f.field :<%= attribute.name %>
|
7
7
|
<%- end -%>
|
8
8
|
.mt-2
|
9
9
|
= f.button :submit
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pg_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 7.6.
|
4
|
+
version: 7.6.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Martín Rosso
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-10-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -674,6 +674,11 @@ files:
|
|
674
674
|
- pg_engine/app/components/date_selector_component.html.slim
|
675
675
|
- pg_engine/app/components/date_selector_component.rb
|
676
676
|
- pg_engine/app/components/flash_container_component.rb
|
677
|
+
- pg_engine/app/components/inline_edit/inline_component.rb
|
678
|
+
- pg_engine/app/components/inline_edit/inline_edit_component.html.slim
|
679
|
+
- pg_engine/app/components/inline_edit/inline_edit_component.rb
|
680
|
+
- pg_engine/app/components/inline_edit/inline_show_component.html.slim
|
681
|
+
- pg_engine/app/components/inline_edit/inline_show_component.rb
|
677
682
|
- pg_engine/app/components/internal_error_component.rb
|
678
683
|
- pg_engine/app/components/modal_component.html.slim
|
679
684
|
- pg_engine/app/components/modal_component.rb
|
@@ -707,6 +712,7 @@ files:
|
|
707
712
|
- pg_engine/app/controllers/users/confirmations_controller.rb
|
708
713
|
- pg_engine/app/controllers/users/dashboard_controller.rb
|
709
714
|
- pg_engine/app/controllers/users/date_jumper_controller.rb
|
715
|
+
- pg_engine/app/controllers/users/inline_edit_controller.rb
|
710
716
|
- pg_engine/app/controllers/users/notifications_controller.rb
|
711
717
|
- pg_engine/app/controllers/users/registrations_controller.rb
|
712
718
|
- pg_engine/app/decorators/account_decorator.rb
|
@@ -902,6 +908,7 @@ files:
|
|
902
908
|
- pg_engine/spec/requests/users/base_controller_spec.rb
|
903
909
|
- pg_engine/spec/requests/users/dashboard_spec.rb
|
904
910
|
- pg_engine/spec/requests/users/date_jumper_spec.rb
|
911
|
+
- pg_engine/spec/requests/users/inline_edit_spec.rb
|
905
912
|
- pg_engine/spec/requests/users/registrations_spec.rb
|
906
913
|
- pg_engine/spec/requests/users/switcher_spec.rb
|
907
914
|
- pg_engine/spec/system/alerts_spec.rb
|