pg_rails 7.3.0 → 7.3.1
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 +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 +24 -19
- 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,24 @@ 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
|
-
start_modal = !helpers.using_modal? && object.class.default_modal
|
68
|
-
|
69
67
|
helpers.content_tag :span, rel: :tooltip, title: 'Modificar' do
|
70
|
-
helpers.link_to edit_object_url
|
71
|
-
|
68
|
+
helpers.link_to edit_object_url,
|
69
|
+
class: "btn btn-sm #{klass}",
|
70
|
+
'data-turbo-frame': 'modal_content',
|
71
|
+
'data-turbo-stream': true do
|
72
72
|
helpers.content_tag(:span, nil, class: clase_icono('pencil')) + text
|
73
73
|
end
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
77
|
-
def url_suffix(start_modal: nil)
|
78
|
-
start_modal ? '?start_modal=true' : ''
|
79
|
-
end
|
80
|
-
|
81
77
|
def show_link(text: '', klass: 'btn-light')
|
82
78
|
return unless Pundit.policy!(Current.user, object).show?
|
83
79
|
|
84
|
-
start_modal = !helpers.using_modal? && object.class.default_modal
|
85
|
-
|
86
80
|
helpers.content_tag :span, rel: :tooltip, title: 'Ver' do
|
87
|
-
helpers.link_to object_url
|
88
|
-
|
81
|
+
helpers.link_to object_url,
|
82
|
+
class: "btn btn-sm #{klass}",
|
83
|
+
'data-turbo-frame': 'modal_content',
|
84
|
+
'data-turbo-stream': true do
|
89
85
|
helpers.content_tag(:span, nil, class: clase_icono('eye-fill')) + text
|
90
86
|
end
|
91
87
|
end
|
@@ -105,11 +101,11 @@ module PgEngine
|
|
105
101
|
def new_link(klass: 'btn-warning')
|
106
102
|
return unless Pundit.policy!(Current.user, object).new?
|
107
103
|
|
108
|
-
start_modal = !helpers.using_modal? && object.class.default_modal
|
109
|
-
|
110
104
|
helpers.content_tag :span, rel: :tooltip, title: submit_default_value do
|
111
|
-
helpers.link_to(new_object_url
|
112
|
-
|
105
|
+
helpers.link_to(new_object_url,
|
106
|
+
class: "btn btn-sm #{klass}",
|
107
|
+
'data-turbo-frame': 'modal_content',
|
108
|
+
'data-turbo-stream': true) do
|
113
109
|
helpers.content_tag(:span, nil,
|
114
110
|
class: clase_icono('plus').to_s) + "<span class='d-none d-sm-inline'> #{submit_default_value}</span>".html_safe
|
115
111
|
end
|
@@ -128,13 +124,22 @@ module PgEngine
|
|
128
124
|
helpers.url_for(target_object)
|
129
125
|
end
|
130
126
|
|
127
|
+
def nested_record
|
128
|
+
# TODO: esto es raro
|
129
|
+
return if !Current.controller.respond_to?(:nested_record) ||
|
130
|
+
Current.controller.nested_record.nil? ||
|
131
|
+
Current.controller.nested_record.instance_of?(object.class)
|
132
|
+
|
133
|
+
Current.controller.nested_record
|
134
|
+
end
|
135
|
+
|
131
136
|
def target_object
|
132
|
-
|
137
|
+
[pg_namespace, nested_record, object].compact
|
133
138
|
end
|
134
139
|
|
135
140
|
def target_new
|
136
141
|
mod_name_sing = object.class.model_name.singular.to_sym
|
137
|
-
|
142
|
+
[:new, pg_namespace, nested_record, mod_name_sing]
|
138
143
|
end
|
139
144
|
|
140
145
|
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
|