pg_rails 7.3.0 → 7.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/pg_associable/app/helpers/pg_associable/form_builder_methods.rb +8 -0
- data/pg_associable/app/helpers/pg_associable/helpers.rb +2 -2
- data/pg_associable/app/javascript/modal_controller.js +66 -4
- data/pg_associable/spec/system/associable_spec.rb +28 -5
- data/pg_engine/app/assets/stylesheets/pg_rails_b5.scss +5 -0
- data/pg_engine/app/components/date_selector_component.rb +2 -2
- data/pg_engine/app/components/modal_content_component.rb +20 -19
- data/pg_engine/app/components/search_bar_component.html.slim +1 -1
- data/pg_engine/app/controllers/admin/accounts_controller.rb +1 -1
- data/pg_engine/app/controllers/admin/email_logs_controller.rb +1 -1
- data/pg_engine/app/controllers/admin/emails_controller.rb +1 -1
- data/pg_engine/app/controllers/admin/user_accounts_controller.rb +1 -1
- data/pg_engine/app/controllers/admin/users_controller.rb +1 -1
- data/pg_engine/app/controllers/concerns/pg_engine/resource.rb +209 -86
- data/pg_engine/app/controllers/pg_engine/base_controller.rb +5 -0
- data/pg_engine/app/controllers/public/mensaje_contactos_controller.rb +1 -1
- data/pg_engine/app/decorators/pg_engine/base_record_decorator.rb +27 -16
- data/pg_engine/app/helpers/pg_engine/form_helper.rb +0 -5
- data/pg_engine/app/helpers/pg_engine/frame_helper.rb +52 -0
- data/pg_engine/app/lib/pg_engine/bootstrap5_breadcrumbs_builder.rb +22 -0
- data/pg_engine/app/lib/pg_engine/filtros_builder.rb +3 -2
- data/pg_engine/app/models/current.rb +1 -1
- data/pg_engine/app/models/pg_engine/base_record.rb +2 -0
- data/pg_engine/app/views/pg_engine/base/edit.html.slim +1 -2
- data/pg_engine/app/views/pg_engine/base/index.html.slim +2 -3
- data/pg_engine/config/initializers/ransack_memory.rb +13 -2
- data/pg_engine/config/locales/es.yml +1 -1
- data/pg_engine/spec/controllers/concerns/pg_engine/resource_helper_spec.rb +0 -2
- data/pg_engine/spec/lib/pg_engine/form_helper_spec.rb +0 -2
- data/pg_engine/spec/system/breadcrumbs_spec.rb +61 -0
- data/pg_engine/spec/system/destroy_spec.rb +1 -1
- data/pg_engine/spec/system/login_spec.rb +1 -1
- data/pg_engine/spec/system/modal_windows_spec.rb +4 -4
- data/pg_layout/app/javascript/application.js +14 -0
- data/pg_layout/app/javascript/config/turbo_rails/index.js +4 -1
- data/pg_layout/app/javascript/controllers/embedded_frame_controller.js +10 -0
- data/pg_layout/app/javascript/controllers/index.js +2 -0
- data/pg_layout/app/javascript/controllers/tooltip_controller.js +8 -0
- data/pg_layout/app/javascript/elements/pg_event.js +2 -1
- data/pg_layout/app/views/layouts/pg_layout/base.html.slim +45 -17
- data/pg_layout/app/views/layouts/pg_layout/containerized.html.slim +1 -1
- data/pg_rails/lib/version.rb +1 -1
- data/pg_rails/scss/bootstrap_overrides.scss +2 -1
- data/pg_rails/scss/pg_rails.scss +8 -1
- data/pg_scaffold/lib/generators/pg_scaffold/templates/controller.rb +2 -4
- metadata +6 -6
- data/pg_engine/app/components/form_modal_component.html.slim +0 -15
- data/pg_engine/app/components/form_modal_component.rb +0 -6
- data/pg_engine/app/components/show_modal_component.html.slim +0 -10
- data/pg_engine/app/components/show_modal_component.rb +0 -7
@@ -1,15 +1,108 @@
|
|
1
1
|
module PgEngine
|
2
2
|
module Resource
|
3
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
3
4
|
def self.included(clazz)
|
4
|
-
|
5
|
+
class << clazz
|
6
|
+
# This is a per class variable, all subclasses of clazz inherit it
|
7
|
+
# BUT **the values are independent between all of them**
|
8
|
+
attr_accessor :nested_class, :nested_key, :clase_modelo
|
9
|
+
|
10
|
+
# TODO: separar los endpoints de la lógica de filtros para evitar esta variable
|
11
|
+
# en Agenda
|
12
|
+
attr_accessor :skip_default_breadcrumb
|
13
|
+
end
|
14
|
+
clazz.delegate :nested_key, :nested_class, :clase_modelo, to: clazz
|
15
|
+
|
16
|
+
clazz.helper_method :nested_class, :nested_key, :clase_modelo
|
17
|
+
clazz.helper_method :nested_record, :nested_id
|
18
|
+
|
5
19
|
clazz.helper_method :atributos_para_listar
|
6
20
|
clazz.helper_method :atributos_para_mostrar
|
7
21
|
clazz.helper_method :current_page_size
|
8
22
|
clazz.helper_method :show_filters?
|
9
23
|
clazz.helper_method :available_page_sizes
|
10
24
|
|
25
|
+
clazz.before_action do
|
26
|
+
# TODO: quitar esto, que se use el attr_accessor
|
27
|
+
# o sea, quitar todas las referencias a @clase_modelo
|
28
|
+
@clase_modelo = clase_modelo
|
29
|
+
end
|
30
|
+
|
31
|
+
clazz.before_action unless: -> { clazz.skip_default_breadcrumb } do
|
32
|
+
if nested_record.present?
|
33
|
+
# Link al nested, siempre que sea no sea un embedded frame
|
34
|
+
# ya que en tal caso se supone que el nested está visible
|
35
|
+
# en el main frame. Además, si es un modal abierto desde
|
36
|
+
# el nested record, no muestro el link al mismo.
|
37
|
+
unless frame_embedded?
|
38
|
+
if modal_targeted? && referred_by?(nested_record)
|
39
|
+
add_breadcrumb nested_record.decorate.to_s_short
|
40
|
+
else
|
41
|
+
add_breadcrumb nested_record.decorate.to_s_short,
|
42
|
+
nested_record.decorate.target_object
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Texto de index pero sin link, porque se supone que es un
|
47
|
+
# embedded index o viene de tal
|
48
|
+
add_breadcrumb clase_modelo.nombre_plural
|
49
|
+
|
50
|
+
elsif !modal_targeted?
|
51
|
+
# Link al index, siempre que no sea un modal, porque en tal
|
52
|
+
# caso se supone que el index está visible en el main frame
|
53
|
+
if clase_modelo.present?
|
54
|
+
add_breadcrumb clase_modelo.nombre_plural,
|
55
|
+
url_for([pg_namespace, nested_record, clase_modelo])
|
56
|
+
else
|
57
|
+
# :nocov:
|
58
|
+
pg_warn 'clase_modelo is nil'
|
59
|
+
# :nocov:
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
11
64
|
clazz.layout :set_layout
|
12
65
|
end
|
66
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
67
|
+
|
68
|
+
def referred_by?(object)
|
69
|
+
url_for(object.decorate.target_object) == request.referer
|
70
|
+
end
|
71
|
+
|
72
|
+
def nested_id
|
73
|
+
return unless nested_key.present? && nested_class.present?
|
74
|
+
|
75
|
+
id = params[nested_key]
|
76
|
+
|
77
|
+
# if using hashid-rails
|
78
|
+
if nested_class.respond_to? :decode_id
|
79
|
+
id = nested_class.decode_id(id)
|
80
|
+
end
|
81
|
+
|
82
|
+
id
|
83
|
+
end
|
84
|
+
|
85
|
+
def nested_record
|
86
|
+
return if nested_id.blank?
|
87
|
+
|
88
|
+
nested_class.find(nested_id)
|
89
|
+
end
|
90
|
+
|
91
|
+
def accepts_turbo_stream?
|
92
|
+
request.headers['Accept'].present? &&
|
93
|
+
request.headers['Accept'].include?('text/vnd.turbo-stream.html')
|
94
|
+
end
|
95
|
+
|
96
|
+
def respond_with_modal?
|
97
|
+
can_open_modal? || modal_targeted?
|
98
|
+
end
|
99
|
+
|
100
|
+
def can_open_modal?
|
101
|
+
request.get? &&
|
102
|
+
clase_modelo.default_modal &&
|
103
|
+
accepts_turbo_stream? &&
|
104
|
+
!in_modal?
|
105
|
+
end
|
13
106
|
|
14
107
|
def set_layout
|
15
108
|
if action_name == 'index'
|
@@ -38,13 +131,9 @@ module PgEngine
|
|
38
131
|
pg_respond_show
|
39
132
|
end
|
40
133
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
elsif klass_or_string.is_a?(String)
|
45
|
-
content = ModalContentComponent.new.with_body_content(klass_or_string)
|
46
|
-
.render_in(view_context)
|
47
|
-
end
|
134
|
+
# FIXME: refactor
|
135
|
+
def respond_with_modal(component)
|
136
|
+
content = component.render_in(view_context)
|
48
137
|
|
49
138
|
if can_open_modal?
|
50
139
|
modal = ModalComponent.new.with_content(content)
|
@@ -55,19 +144,28 @@ module PgEngine
|
|
55
144
|
end
|
56
145
|
|
57
146
|
def new
|
58
|
-
if
|
59
|
-
|
147
|
+
if can_open_modal?
|
148
|
+
path = [request.path, request.query_string].compact.join('?')
|
149
|
+
component = ModalContentComponent.new(src: path)
|
150
|
+
respond_with_modal(component)
|
60
151
|
else
|
61
152
|
add_breadcrumb instancia_modelo.submit_default_value
|
62
153
|
end
|
63
154
|
end
|
64
155
|
|
65
156
|
def edit
|
66
|
-
if
|
67
|
-
|
157
|
+
if can_open_modal?
|
158
|
+
path = [request.path, request.query_string].compact.join('?')
|
159
|
+
component = ModalContentComponent.new(src: path)
|
160
|
+
respond_with_modal(component)
|
68
161
|
else
|
69
|
-
|
70
|
-
|
162
|
+
if modal_targeted? && referred_by?(instancia_modelo)
|
163
|
+
add_breadcrumb instancia_modelo.to_s_short
|
164
|
+
else
|
165
|
+
add_breadcrumb instancia_modelo.to_s_short,
|
166
|
+
instancia_modelo.target_object
|
167
|
+
end
|
168
|
+
add_breadcrumb 'Modificando'
|
71
169
|
end
|
72
170
|
end
|
73
171
|
|
@@ -87,36 +185,59 @@ module PgEngine
|
|
87
185
|
protected
|
88
186
|
|
89
187
|
def default_sort
|
90
|
-
|
188
|
+
'id desc'
|
91
189
|
end
|
92
190
|
|
93
191
|
def available_page_sizes
|
94
|
-
[10, 20, 30, 50, 100].push(current_page_size).uniq.sort
|
192
|
+
[5, 10, 20, 30, 50, 100].push(current_page_size).uniq.sort
|
193
|
+
end
|
194
|
+
|
195
|
+
def show_filters_by_default?
|
196
|
+
true
|
197
|
+
end
|
198
|
+
|
199
|
+
def filters_applied?
|
200
|
+
params[RansackMemory::Core.config[:param].presence || :q].present?
|
201
|
+
end
|
202
|
+
|
203
|
+
def session_key_identifier
|
204
|
+
::RansackMemory::Core.config[:session_key_format]
|
205
|
+
.gsub('%controller_name%', controller_path.parameterize.underscore)
|
206
|
+
.gsub('%action_name%', action_name)
|
207
|
+
.gsub('%request_format%', request.format.symbol.to_s)
|
208
|
+
.gsub('%turbo_frame%', request.headers['Turbo-Frame'] || 'top')
|
209
|
+
# FIXME: rename to main?
|
95
210
|
end
|
96
211
|
|
97
212
|
def show_filters?
|
98
|
-
|
99
|
-
|
213
|
+
return true if filters_applied?
|
214
|
+
|
215
|
+
idtf = "show-filters_#{session_key_identifier}"
|
100
216
|
|
101
217
|
if params[:ocultar_filtros]
|
102
|
-
session[idtf] =
|
218
|
+
session[idtf] = false
|
103
219
|
elsif params[:mostrar_filtros]
|
104
220
|
session[idtf] = true
|
105
221
|
end
|
106
222
|
|
107
|
-
session[idtf]
|
223
|
+
if session[idtf].nil?
|
224
|
+
show_filters_by_default?
|
225
|
+
else
|
226
|
+
session[idtf]
|
227
|
+
end
|
108
228
|
end
|
109
229
|
|
110
230
|
def current_page_size
|
111
|
-
|
112
|
-
|
231
|
+
aux = params[:page_size].presence&.to_i
|
232
|
+
if aux.present? && aux.positive?
|
233
|
+
session[page_size_session_key] = aux
|
113
234
|
end
|
114
235
|
|
115
236
|
session[page_size_session_key].presence || default_page_size
|
116
237
|
end
|
117
238
|
|
118
239
|
def page_size_session_key
|
119
|
-
"#{
|
240
|
+
"page_size_#{session_key_identifier}"
|
120
241
|
end
|
121
242
|
|
122
243
|
def default_page_size
|
@@ -126,22 +247,26 @@ module PgEngine
|
|
126
247
|
def pg_respond_update
|
127
248
|
object = instancia_modelo
|
128
249
|
if (@saved = object.save)
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
250
|
+
respond_to do |format|
|
251
|
+
format.html do
|
252
|
+
if in_modal?
|
253
|
+
body = <<~HTML.html_safe
|
254
|
+
<pg-event data-event-name="pg:record-updated" data-turbo-temporary
|
255
|
+
data-response='#{object.decorate.to_json}'></pg-event>
|
256
|
+
HTML
|
257
|
+
render html: ModalContentComponent.new.with_content(body)
|
258
|
+
.render_in(view_context)
|
259
|
+
else
|
260
|
+
redirect_to object.decorate.target_object
|
261
|
+
end
|
262
|
+
end
|
263
|
+
format.json do
|
264
|
+
render json: object.decorate.as_json
|
265
|
+
end
|
138
266
|
end
|
139
|
-
elsif in_modal?
|
140
|
-
render html: FormModalComponent.new(instancia_modelo.decorate)
|
141
|
-
.render_in(view_context)
|
142
267
|
else
|
143
268
|
add_breadcrumb instancia_modelo.decorate.to_s_short, instancia_modelo.decorate.target_object
|
144
|
-
add_breadcrumb '
|
269
|
+
add_breadcrumb 'Modificando'
|
145
270
|
# TODO: esto solucionaría el problema?
|
146
271
|
# self.instancia_modelo = instancia_modelo.decorate
|
147
272
|
#
|
@@ -157,15 +282,10 @@ module PgEngine
|
|
157
282
|
<pg-event data-event-name="pg:record-created" data-turbo-temporary
|
158
283
|
data-response='#{object.decorate.to_json}'></pg-event>
|
159
284
|
HTML
|
160
|
-
render
|
161
|
-
.render_in(view_context)
|
162
|
-
|
285
|
+
render turbo_stream: turbo_stream.append(current_turbo_frame, body)
|
163
286
|
else
|
164
287
|
redirect_to object.decorate.target_object
|
165
288
|
end
|
166
|
-
elsif in_modal?
|
167
|
-
render html: FormModalComponent.new(instancia_modelo.decorate)
|
168
|
-
.render_in(view_context)
|
169
289
|
else
|
170
290
|
add_breadcrumb instancia_modelo.decorate.submit_default_value
|
171
291
|
# TODO: esto solucionaría el problema?
|
@@ -181,35 +301,17 @@ module PgEngine
|
|
181
301
|
format.html { render_listing }
|
182
302
|
format.xlsx do
|
183
303
|
render xlsx: 'download',
|
184
|
-
filename: "#{
|
304
|
+
filename: "#{clase_modelo.nombre_plural.gsub(' ', '-').downcase}" \
|
185
305
|
"-#{Time.zone.now.strftime('%Y-%m-%d-%H.%M.%S')}.xlsx"
|
186
306
|
end
|
187
307
|
end
|
188
308
|
end
|
189
309
|
|
190
|
-
def accepts_turbo_stream?
|
191
|
-
request.headers['Accept'].present? &&
|
192
|
-
request.headers['Accept'].include?('text/vnd.turbo-stream.html')
|
193
|
-
end
|
194
|
-
|
195
|
-
def in_modal?
|
196
|
-
request.headers['turbo-frame'] == 'modal_generic'
|
197
|
-
end
|
198
|
-
|
199
|
-
def respond_with_modal?
|
200
|
-
can_open_modal? || in_modal?
|
201
|
-
end
|
202
|
-
|
203
|
-
def can_open_modal?
|
204
|
-
request.get? &&
|
205
|
-
params[:start_modal] == 'true' &&
|
206
|
-
accepts_turbo_stream? &&
|
207
|
-
!in_modal?
|
208
|
-
end
|
209
|
-
|
210
310
|
def pg_respond_show
|
211
|
-
if
|
212
|
-
|
311
|
+
if can_open_modal?
|
312
|
+
path = [request.path, request.query_string].compact.join('?')
|
313
|
+
component = ModalContentComponent.new(src: path)
|
314
|
+
respond_with_modal(component)
|
213
315
|
else
|
214
316
|
add_breadcrumb instancia_modelo.to_s_short, instancia_modelo.target_object
|
215
317
|
end
|
@@ -219,14 +321,16 @@ module PgEngine
|
|
219
321
|
"#{model.model_name.human} #{model.gender == 'f' ? 'borrada' : 'borrado'}"
|
220
322
|
end
|
221
323
|
|
324
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
222
325
|
def pg_respond_destroy(model, redirect_url = nil)
|
223
326
|
if destroy_model(model)
|
224
|
-
|
327
|
+
# FIXME: rename to main
|
328
|
+
if turbo_frame? && current_turbo_frame != 'top'
|
225
329
|
body = <<~HTML.html_safe
|
226
330
|
<pg-event data-event-name="pg:record-destroyed" data-turbo-temporary>
|
227
331
|
</pg-event>
|
228
332
|
HTML
|
229
|
-
|
333
|
+
render turbo_stream: turbo_stream.append(current_turbo_frame, body)
|
230
334
|
elsif redirect_url.present?
|
231
335
|
redirect_to redirect_url, notice: destroyed_message(model), status: :see_other
|
232
336
|
elsif accepts_turbo_stream?
|
@@ -251,6 +355,7 @@ module PgEngine
|
|
251
355
|
redirect_back(fallback_location: root_path, status: 303)
|
252
356
|
end
|
253
357
|
end
|
358
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
254
359
|
|
255
360
|
def destroy_model(model)
|
256
361
|
@error_message = 'No se pudo eliminar el registro'
|
@@ -272,17 +377,22 @@ module PgEngine
|
|
272
377
|
end
|
273
378
|
|
274
379
|
def render_listing
|
275
|
-
|
380
|
+
total = @collection.count
|
381
|
+
current_page = params[:page].presence&.to_i || 1
|
382
|
+
if current_page_size * (current_page - 1) > total
|
383
|
+
current_page = (total.to_f / current_page_size).ceil
|
384
|
+
end
|
385
|
+
@collection = @collection.page(current_page).per(current_page_size)
|
276
386
|
@records_filtered = default_scope_for_current_model.any? if @collection.empty?
|
277
387
|
end
|
278
388
|
|
279
389
|
def buscar_instancia
|
280
|
-
if Object.const_defined?('FriendlyId') &&
|
281
|
-
|
282
|
-
elsif
|
283
|
-
|
390
|
+
if Object.const_defined?('FriendlyId') && clase_modelo.is_a?(FriendlyId)
|
391
|
+
clase_modelo.friendly.find(params[:id])
|
392
|
+
elsif clase_modelo.respond_to? :find_by_hashid!
|
393
|
+
clase_modelo.find_by_hashid!(params[:id])
|
284
394
|
else
|
285
|
-
|
395
|
+
clase_modelo.find(params[:id])
|
286
396
|
end
|
287
397
|
rescue ActiveRecord::RecordNotFound
|
288
398
|
raise PgEngine::PageNotFoundError
|
@@ -290,7 +400,10 @@ module PgEngine
|
|
290
400
|
|
291
401
|
def set_instancia_modelo
|
292
402
|
if action_name.in? %w[new create]
|
293
|
-
self.instancia_modelo =
|
403
|
+
self.instancia_modelo = clase_modelo.new(modelo_params)
|
404
|
+
if nested_id.present?
|
405
|
+
instancia_modelo.send("#{nested_key}=", nested_id)
|
406
|
+
end
|
294
407
|
else
|
295
408
|
self.instancia_modelo = buscar_instancia
|
296
409
|
|
@@ -323,12 +436,7 @@ module PgEngine
|
|
323
436
|
end
|
324
437
|
|
325
438
|
def nombre_modelo
|
326
|
-
|
327
|
-
end
|
328
|
-
|
329
|
-
def clase_modelo
|
330
|
-
# agarro la variable o intento con el nombre del controller
|
331
|
-
@clase_modelo ||= self.class.name.singularize.gsub('Controller', '').constantize
|
439
|
+
clase_modelo.name.underscore
|
332
440
|
end
|
333
441
|
|
334
442
|
def filtros_y_policy(campos, dflt_sort = nil)
|
@@ -337,20 +445,35 @@ module PgEngine
|
|
337
445
|
)
|
338
446
|
scope = policy_scope(clase_modelo)
|
339
447
|
|
340
|
-
|
448
|
+
if nested_id.present?
|
449
|
+
scope = scope.where(nested_key => nested_id)
|
450
|
+
scope = scope.undiscarded if scope.respond_to?(:undiscarded)
|
451
|
+
elsif scope.respond_to?(:kept)
|
452
|
+
scope = scope.kept
|
453
|
+
end
|
454
|
+
# Soft deleted
|
341
455
|
|
342
456
|
shared_context = Ransack::Adapters::ActiveRecord::Context.new(scope)
|
343
|
-
@q =
|
344
|
-
|
457
|
+
@q = clase_modelo.ransack(params[:q], context: shared_context)
|
345
458
|
@q.sorts = dflt_sort if @q.sorts.empty? && dflt_sort.present?
|
346
459
|
|
347
460
|
shared_context.evaluate(@q)
|
348
461
|
end
|
349
462
|
|
350
463
|
def default_scope_for_current_model
|
351
|
-
|
352
|
-
|
353
|
-
|
464
|
+
scope = policy_scope(clase_modelo)
|
465
|
+
|
466
|
+
if nested_id.present?
|
467
|
+
scope = scope.where(nested_key => nested_id)
|
468
|
+
|
469
|
+
# Skip nested discarded check
|
470
|
+
scope = scope.undiscarded if scope.respond_to?(:undiscarded)
|
471
|
+
elsif scope.respond_to?(:kept)
|
472
|
+
scope = scope.kept
|
473
|
+
end
|
474
|
+
# Soft deleted, including nested discarded check
|
475
|
+
|
476
|
+
scope
|
354
477
|
end
|
355
478
|
end
|
356
479
|
end
|
@@ -3,6 +3,10 @@
|
|
3
3
|
module PgEngine
|
4
4
|
# rubocop:disable Rails/ApplicationController
|
5
5
|
class BaseController < ActionController::Base
|
6
|
+
before_action do
|
7
|
+
Current.controller = self
|
8
|
+
end
|
9
|
+
|
6
10
|
# rubocop:enable Rails/ApplicationController
|
7
11
|
include Pundit::Authorization
|
8
12
|
include PrintHelper
|
@@ -10,6 +14,7 @@ module PgEngine
|
|
10
14
|
include FlashHelper
|
11
15
|
include RouteHelper
|
12
16
|
include PgAssociable::Helpers
|
17
|
+
include FrameHelper
|
13
18
|
|
14
19
|
class Redirect < PgEngine::Error
|
15
20
|
attr_accessor :url
|
@@ -49,7 +49,7 @@ module PgEngine
|
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
|
-
def destroy_link(confirm_text: '¿
|
52
|
+
def destroy_link(confirm_text: '¿Confirmás que querés borrar el registro?', klass: 'btn-light', redirect_to: nil)
|
53
53
|
return unless Pundit.policy!(Current.user, object).destroy?
|
54
54
|
|
55
55
|
helpers.content_tag :span, rel: :tooltip, title: 'Eliminar' do
|
@@ -64,28 +64,28 @@ module PgEngine
|
|
64
64
|
def edit_link(text: ' Modificar', klass: 'btn-warning')
|
65
65
|
return unless Pundit.policy!(Current.user, object).edit?
|
66
66
|
|
67
|
-
|
67
|
+
modal = object.class.default_modal
|
68
68
|
|
69
69
|
helpers.content_tag :span, rel: :tooltip, title: 'Modificar' do
|
70
|
-
helpers.link_to edit_object_url
|
71
|
-
|
70
|
+
helpers.link_to edit_object_url,
|
71
|
+
class: "btn btn-sm #{klass}",
|
72
|
+
'data-turbo-frame': modal ? 'modal_content' : '_top',
|
73
|
+
'data-turbo-stream': modal do
|
72
74
|
helpers.content_tag(:span, nil, class: clase_icono('pencil')) + text
|
73
75
|
end
|
74
76
|
end
|
75
77
|
end
|
76
78
|
|
77
|
-
def url_suffix(start_modal: nil)
|
78
|
-
start_modal ? '?start_modal=true' : ''
|
79
|
-
end
|
80
|
-
|
81
79
|
def show_link(text: '', klass: 'btn-light')
|
82
80
|
return unless Pundit.policy!(Current.user, object).show?
|
83
81
|
|
84
|
-
|
82
|
+
modal = object.class.default_modal
|
85
83
|
|
86
84
|
helpers.content_tag :span, rel: :tooltip, title: 'Ver' do
|
87
|
-
helpers.link_to object_url
|
88
|
-
|
85
|
+
helpers.link_to object_url,
|
86
|
+
class: "btn btn-sm #{klass}",
|
87
|
+
'data-turbo-frame': modal ? 'modal_content' : '_top',
|
88
|
+
'data-turbo-stream': modal do
|
89
89
|
helpers.content_tag(:span, nil, class: clase_icono('eye-fill')) + text
|
90
90
|
end
|
91
91
|
end
|
@@ -105,11 +105,13 @@ module PgEngine
|
|
105
105
|
def new_link(klass: 'btn-warning')
|
106
106
|
return unless Pundit.policy!(Current.user, object).new?
|
107
107
|
|
108
|
-
|
108
|
+
modal = object.class.default_modal
|
109
109
|
|
110
110
|
helpers.content_tag :span, rel: :tooltip, title: submit_default_value do
|
111
|
-
helpers.link_to(new_object_url
|
112
|
-
|
111
|
+
helpers.link_to(new_object_url,
|
112
|
+
class: "btn btn-sm #{klass}",
|
113
|
+
'data-turbo-frame': modal ? 'modal_content' : '_top',
|
114
|
+
'data-turbo-stream': modal) do
|
113
115
|
helpers.content_tag(:span, nil,
|
114
116
|
class: clase_icono('plus').to_s) + "<span class='d-none d-sm-inline'> #{submit_default_value}</span>".html_safe
|
115
117
|
end
|
@@ -128,13 +130,22 @@ module PgEngine
|
|
128
130
|
helpers.url_for(target_object)
|
129
131
|
end
|
130
132
|
|
133
|
+
def nested_record
|
134
|
+
# TODO: esto es raro
|
135
|
+
return if !Current.controller.respond_to?(:nested_record) ||
|
136
|
+
Current.controller.nested_record.nil? ||
|
137
|
+
Current.controller.nested_record.instance_of?(object.class)
|
138
|
+
|
139
|
+
Current.controller.nested_record
|
140
|
+
end
|
141
|
+
|
131
142
|
def target_object
|
132
|
-
|
143
|
+
[pg_namespace, nested_record, object].compact
|
133
144
|
end
|
134
145
|
|
135
146
|
def target_new
|
136
147
|
mod_name_sing = object.class.model_name.singular.to_sym
|
137
|
-
|
148
|
+
[:new, pg_namespace, nested_record, mod_name_sing]
|
138
149
|
end
|
139
150
|
|
140
151
|
def target_index
|
@@ -2,10 +2,6 @@
|
|
2
2
|
|
3
3
|
module PgEngine
|
4
4
|
module FormHelper
|
5
|
-
def using_modal?
|
6
|
-
@using_modal || controller.instance_variable_get(:@using_modal)
|
7
|
-
end
|
8
|
-
|
9
5
|
# rubocop:disable Metrics/CyclomaticComplexity
|
10
6
|
def pg_form_for(object, *args, &block_passed)
|
11
7
|
resource = object
|
@@ -39,7 +35,6 @@ module PgEngine
|
|
39
35
|
block_with_additives = lambda do |f|
|
40
36
|
ret = ''.html_safe
|
41
37
|
ret += f.mensajes_de_error if options[:render_errors]
|
42
|
-
# ret += hidden_field_tag(:using_modal, true) if using_modal?
|
43
38
|
ret += capture(f, &block_passed)
|
44
39
|
ret
|
45
40
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module PgEngine
|
2
|
+
module FrameHelper
|
3
|
+
# Will the current view rendered in a modal?
|
4
|
+
def using_modal?
|
5
|
+
controller.instance_variable_get(:@using_modal) ||
|
6
|
+
modal_targeted?
|
7
|
+
end
|
8
|
+
|
9
|
+
def using_modal2?
|
10
|
+
@using_modal || modal_targeted?
|
11
|
+
end
|
12
|
+
|
13
|
+
def in_modal?
|
14
|
+
request.headers['Modal-Opened'] == 'true'
|
15
|
+
end
|
16
|
+
|
17
|
+
def current_turbo_frame
|
18
|
+
request.headers['Turbo-Frame']
|
19
|
+
end
|
20
|
+
|
21
|
+
def turbo_frame?
|
22
|
+
current_turbo_frame.present?
|
23
|
+
end
|
24
|
+
|
25
|
+
def modal_targeted?
|
26
|
+
current_turbo_frame == 'modal_content'
|
27
|
+
end
|
28
|
+
|
29
|
+
def frame_embedded?
|
30
|
+
turbo_frame? && current_turbo_frame.include?('embedded')
|
31
|
+
end
|
32
|
+
|
33
|
+
def embed_index(object, key)
|
34
|
+
content_tag(:div, 'data-controller': 'embedded-frame') do
|
35
|
+
turbo_frame_tag "embedded--#{key}",
|
36
|
+
refresh: :morph, src: url_for([pg_namespace, object, key]) do
|
37
|
+
content_tag(:p, class: 'p text-body-secondary text-center') { 'Cargando...' }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def nav_bg
|
43
|
+
if frame_embedded?
|
44
|
+
'bg-warning bg-opacity-25'
|
45
|
+
elsif using_modal?
|
46
|
+
'bg-warning bg-opacity-50'
|
47
|
+
else
|
48
|
+
'bg-primary-subtle'
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module PgEngine
|
2
|
+
class Bootstrap5BreadcrumbsBuilder < BreadcrumbsOnRails::Breadcrumbs::Builder
|
3
|
+
def render
|
4
|
+
@elements.collect do |element|
|
5
|
+
render_element(element)
|
6
|
+
end.join(@options[:separator] || '')
|
7
|
+
end
|
8
|
+
|
9
|
+
def render_element(element)
|
10
|
+
content = if element.path.nil?
|
11
|
+
compute_name(element)
|
12
|
+
else
|
13
|
+
# TODO: add aria-current="page"
|
14
|
+
@context.link_to_unless_current(
|
15
|
+
compute_name(element), compute_path(element), element.options
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
@context.content_tag('li', content, class: 'breadcrumb-item')
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -64,11 +64,12 @@ module PgEngine
|
|
64
64
|
@filtros[campo][:scope_asociacion] = block
|
65
65
|
end
|
66
66
|
|
67
|
+
# FIXME: deprecar
|
67
68
|
def filtrar(query, parametros = nil)
|
68
|
-
|
69
|
+
parametros_controller if parametros.nil?
|
69
70
|
|
70
71
|
# Filtro soft deleted
|
71
|
-
query = query.kept if query.respond_to?(:kept)
|
72
|
+
query = query.kept if query.respond_to?(:kept)
|
72
73
|
|
73
74
|
query
|
74
75
|
end
|