pg_rails 7.6.17 → 7.6.19
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/javascript/modal_controller.js +17 -1
- data/pg_engine/app/assets/stylesheets/pg_rails_b5.scss +8 -1
- data/pg_engine/app/components/inline_edit/inline_show_component.html.slim +2 -1
- data/pg_engine/app/components/search_bar_toggler_component.html.slim +5 -3
- data/pg_engine/app/controllers/admin/accounts_controller.rb +0 -4
- data/pg_engine/app/controllers/admin/email_logs_controller.rb +0 -4
- data/pg_engine/app/controllers/admin/emails_controller.rb +0 -4
- data/pg_engine/app/controllers/admin/simple_user_notifiers_controller.rb +0 -2
- data/pg_engine/app/controllers/admin/user_accounts_controller.rb +0 -4
- data/pg_engine/app/controllers/admin/users_controller.rb +0 -4
- data/pg_engine/app/controllers/concerns/pg_engine/resource.rb +121 -41
- data/pg_engine/app/controllers/public/mensaje_contactos_controller.rb +0 -4
- data/pg_engine/app/controllers/users/accounts_controller.rb +0 -4
- data/pg_engine/app/decorators/pg_engine/base_record_decorator.rb +39 -13
- data/pg_engine/app/helpers/pg_engine/index_helper.rb +17 -3
- data/pg_engine/app/helpers/pg_engine/route_helper.rb +4 -0
- data/pg_engine/app/lib/pg_engine/filtros_builder.rb +7 -9
- data/pg_engine/app/models/account.rb +2 -0
- data/pg_engine/app/models/concerns/pg_engine/naming.rb +5 -0
- data/pg_engine/app/models/pg_engine/base_record.rb +1 -4
- data/pg_engine/app/models/user.rb +1 -1
- data/pg_engine/app/policies/account_policy.rb +9 -9
- data/pg_engine/app/policies/pg_engine/base_policy.rb +15 -3
- data/pg_engine/app/views/admin/accounts/show.html.slim +0 -7
- data/pg_engine/app/views/admin/email_logs/show.html.slim +0 -7
- data/pg_engine/app/views/admin/emails/show.html.slim +0 -7
- data/pg_engine/app/views/admin/simple_user_notifiers/show.html.slim +0 -5
- data/pg_engine/app/views/admin/user_accounts/show.html.slim +0 -7
- data/pg_engine/app/views/admin/users/show.html.slim +1 -5
- data/pg_engine/app/views/pg_engine/base/index.html.slim +40 -15
- data/pg_engine/config/locales/es.rb +42 -0
- data/pg_engine/config/locales/es.yml +1 -6
- data/pg_engine/lib/pg_engine/route_helpers.rb +5 -0
- data/pg_engine/spec/controllers/admin/accounts_controller_spec.rb +4 -9
- data/pg_engine/spec/controllers/admin/email_logs_controller_spec.rb +4 -4
- data/pg_engine/spec/controllers/admin/emails_controller_spec.rb +4 -4
- data/pg_engine/spec/controllers/admin/user_accounts_controller_spec.rb +4 -4
- data/pg_engine/spec/controllers/admin/users_controller_spec.rb +4 -9
- data/pg_engine/spec/requests/resource_spec.rb +84 -0
- data/pg_engine/spec/requests/users/switcher_spec.rb +2 -2
- data/pg_engine/spec/system/breadcrumbs_spec.rb +9 -21
- data/pg_engine/spec/system/destroy_spec.rb +3 -3
- data/pg_engine/spec/system/login_spec.rb +1 -1
- data/pg_engine/spec/system/modal_windows_spec.rb +5 -5
- data/pg_engine/spec/system/tenants_spec.rb +2 -2
- data/pg_layout/app/javascript/application.js +4 -2
- data/pg_layout/app/javascript/controllers/embedded_frame_controller.js +4 -0
- data/pg_layout/app/views/layouts/pg_layout/base.html.slim +3 -1
- data/pg_layout/app/views/layouts/pg_layout/show.html.slim +10 -0
- data/pg_rails/lib/version.rb +1 -1
- data/pg_scaffold/lib/generators/pg_rspec/scaffold/templates/controller_spec.rb +4 -11
- data/pg_scaffold/lib/generators/pg_scaffold/templates/controller.rb +1 -5
- data/pg_scaffold/lib/generators/pg_slim/templates/show.html.slim +0 -7
- metadata +5 -3
- data/pg_engine/app/components/actions_component.rb +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e3c2a1c474c0e93c88c3403a1c029908571afa71299d67bb61333f1dc41df4d6
|
4
|
+
data.tar.gz: 5bc01cc28aac8510bdac8d9e2b8b50f68c60d047d70dc0e47c693211dc4462a7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: af345cd05556af2813a3c492f4d8d76565f87eb34f7607a197ce9509ac35f4fbaea46029a9053f0768add6185d9940246360cf6c74705c0d88938c28e9b0fcce
|
7
|
+
data.tar.gz: f357484dbc3a12c00332574f8b7389020193a0a456b2ec0b1af8b1cd340c3a0c2855eea40ba8df125720283ddea2f741db8a45c0b8c3588348b5481342b8c6a9
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import { Controller } from '@hotwired/stimulus'
|
2
2
|
import * as bootstrap from 'bootstrap'
|
3
|
+
import { Rollbar } from 'rollbar'
|
3
4
|
|
4
5
|
export default class extends Controller {
|
5
6
|
static outlets = ['asociable']
|
@@ -41,7 +42,13 @@ export default class extends Controller {
|
|
41
42
|
this.reloadTop()
|
42
43
|
ev.stopPropagation()
|
43
44
|
} else {
|
44
|
-
|
45
|
+
if (ev.data.dataset.reload) {
|
46
|
+
this.reload()
|
47
|
+
this.reloadTop()
|
48
|
+
ev.stopPropagation()
|
49
|
+
} else {
|
50
|
+
this.back(ev)
|
51
|
+
}
|
45
52
|
}
|
46
53
|
})
|
47
54
|
|
@@ -73,6 +80,15 @@ export default class extends Controller {
|
|
73
80
|
}
|
74
81
|
}
|
75
82
|
|
83
|
+
reload () {
|
84
|
+
const frame = this.element.querySelector('turbo-frame')
|
85
|
+
if (frame.attributes.src) {
|
86
|
+
frame.reload()
|
87
|
+
} else {
|
88
|
+
Rollbar.error('Modal without frame')
|
89
|
+
}
|
90
|
+
}
|
91
|
+
|
76
92
|
reloadTop () {
|
77
93
|
// FIXME: rename to main?
|
78
94
|
const topFrame = document.querySelector('#top')
|
@@ -71,11 +71,18 @@ input[type=datetime-local], input[type=datetime] {
|
|
71
71
|
.listado {
|
72
72
|
td, th {
|
73
73
|
padding: 0.25rem 1rem;
|
74
|
+
|
75
|
+
&:has(.actions-wrapper) {
|
76
|
+
width: 0.1%;
|
77
|
+
border-right: 1px solid #c1c1c1;
|
78
|
+
padding: 0 1rem;
|
79
|
+
vertical-align: middle;
|
80
|
+
}
|
74
81
|
}
|
75
82
|
}
|
76
83
|
.listado .actions-wrapper {
|
77
84
|
display: flex;
|
78
|
-
justify-content: flex-end;
|
85
|
+
// justify-content: flex-end;
|
79
86
|
gap: 4px;
|
80
87
|
|
81
88
|
.btn-sm {
|
@@ -1,4 +1,5 @@
|
|
1
|
-
- if
|
1
|
+
- if Current.namespace == :users && \
|
2
|
+
@model.class.inline_editable?(@unsuffixed_attribute) && helpers.policy(@model).edit?
|
2
3
|
= helpers.turbo_frame_tag(@frame_id, class: 'inline-edit')
|
3
4
|
- if @record_updated
|
4
5
|
pg-event[data-event-name="pg:record-updated" data-inline="true" data-turbo-temporary=""
|
@@ -1,8 +1,10 @@
|
|
1
1
|
- if helpers.show_filters?
|
2
2
|
= link_to url_for(ocultar_filtros: 1, cancel_filter: 'true'),
|
3
|
-
class: '
|
3
|
+
class: 'dropdown-item icon-link' do
|
4
|
+
i.bi.bi-funnel-fill.lh-1
|
4
5
|
| Ocultar filtros
|
5
6
|
- else
|
6
7
|
= link_to url_for(mostrar_filtros: 1),
|
7
|
-
class: '
|
8
|
-
|
8
|
+
class: 'dropdown-item icon-link' do
|
9
|
+
i.bi.bi-funnel-fill.lh-1
|
10
|
+
| Mostrar filtros
|
@@ -8,10 +8,6 @@ module Admin
|
|
8
8
|
|
9
9
|
self.clase_modelo = EmailLog
|
10
10
|
|
11
|
-
before_action(only: :index) { authorize EmailLog }
|
12
|
-
|
13
|
-
before_action :set_instancia_modelo, only: %i[new create show edit update destroy]
|
14
|
-
|
15
11
|
before_action do
|
16
12
|
@actions = [
|
17
13
|
["Mailgun sync: #{ENV.fetch('MAILGUN_DOMAIN', nil)}", mailgun_sync_admin_email_logs_path, {
|
@@ -8,10 +8,6 @@ module Admin
|
|
8
8
|
|
9
9
|
self.clase_modelo = Email
|
10
10
|
|
11
|
-
before_action(only: :index) { authorize Email }
|
12
|
-
|
13
|
-
before_action :set_instancia_modelo, only: %i[new create show edit update destroy]
|
14
|
-
|
15
11
|
after_action only: :create do
|
16
12
|
if @saved
|
17
13
|
PgEngine::AdminMailer.with(email_object: @email).admin_mail.deliver_later
|
@@ -10,10 +10,6 @@ module Admin
|
|
10
10
|
self.nested_class = Account
|
11
11
|
self.nested_key = :account_id
|
12
12
|
|
13
|
-
before_action(only: :index) { authorize UserAccount }
|
14
|
-
|
15
|
-
before_action :set_instancia_modelo, only: %i[new create show edit update destroy]
|
16
|
-
|
17
13
|
private
|
18
14
|
|
19
15
|
def atributos_permitidos
|
@@ -8,14 +8,10 @@ module Admin
|
|
8
8
|
|
9
9
|
self.clase_modelo = User
|
10
10
|
|
11
|
-
before_action(only: :index) { authorize User }
|
12
|
-
|
13
11
|
before_action only: %i[update] do
|
14
12
|
params[:user].delete(:password) if params[:user][:password].blank?
|
15
13
|
end
|
16
14
|
|
17
|
-
before_action :set_instancia_modelo, only: %i[new create show edit update destroy]
|
18
|
-
|
19
15
|
def create
|
20
16
|
@user.skip_confirmation!
|
21
17
|
@user.orphan = true
|
@@ -10,6 +10,9 @@ module PgEngine
|
|
10
10
|
# TODO: separar los endpoints de la lógica de filtros para evitar esta variable
|
11
11
|
# en Agenda
|
12
12
|
attr_accessor :skip_default_breadcrumb
|
13
|
+
|
14
|
+
# Skip set_instancia_modelo && authorize
|
15
|
+
attr_accessor :skip_default_hooks
|
13
16
|
end
|
14
17
|
clazz.delegate :nested_key, :nested_class, :clase_modelo, to: clazz
|
15
18
|
|
@@ -22,6 +25,7 @@ module PgEngine
|
|
22
25
|
clazz.helper_method :show_filters?
|
23
26
|
clazz.helper_method :available_page_sizes
|
24
27
|
clazz.helper_method :column_options_for
|
28
|
+
clazz.helper_method :instancia_modelo
|
25
29
|
|
26
30
|
clazz.before_action do
|
27
31
|
# TODO: quitar esto, que se use el attr_accessor
|
@@ -29,6 +33,14 @@ module PgEngine
|
|
29
33
|
@clase_modelo = clase_modelo
|
30
34
|
end
|
31
35
|
|
36
|
+
clazz.before_action(only: %i[index archived], unless: -> { clazz.skip_default_hooks }) do
|
37
|
+
authorize clase_modelo
|
38
|
+
end
|
39
|
+
|
40
|
+
clazz.before_action :set_instancia_modelo,
|
41
|
+
only: %i[new create show edit update destroy archive restore],
|
42
|
+
unless: -> { clazz.skip_default_hooks }
|
43
|
+
|
32
44
|
clazz.before_action unless: -> { clazz.skip_default_breadcrumb } do
|
33
45
|
if nested_record.present?
|
34
46
|
# Link al nested, siempre que sea no sea un embedded frame
|
@@ -40,20 +52,28 @@ module PgEngine
|
|
40
52
|
add_breadcrumb nested_record.decorate.to_s_short
|
41
53
|
else
|
42
54
|
add_breadcrumb nested_record.decorate.to_s_short,
|
43
|
-
nested_record.decorate.target_object
|
55
|
+
path_for(nested_record.decorate.target_object)
|
44
56
|
end
|
45
57
|
end
|
46
58
|
|
47
|
-
|
48
|
-
|
49
|
-
|
59
|
+
if action_name == 'archived'
|
60
|
+
# En el listado de archivados tiene que haber un link al listado
|
61
|
+
# principal
|
62
|
+
add_breadcrumb clase_modelo.nombre_plural,
|
63
|
+
path_for([pg_namespace, nested_record, clase_modelo])
|
64
|
+
else
|
65
|
+
# Texto de index pero sin link, porque se supone que es un
|
66
|
+
# embedded index o es un show dentro de un embedded y por ende
|
67
|
+
# el paso atrás no tiene que ser el listado sino el show del parent
|
68
|
+
add_breadcrumb clase_modelo.nombre_plural
|
69
|
+
end
|
50
70
|
|
51
71
|
elsif !modal_targeted?
|
52
72
|
# Link al index, siempre que no sea un modal, porque en tal
|
53
73
|
# caso se supone que el index está visible en el main frame
|
54
74
|
if clase_modelo.present?
|
55
75
|
add_breadcrumb clase_modelo.nombre_plural,
|
56
|
-
|
76
|
+
path_for([pg_namespace, nested_record, clase_modelo])
|
57
77
|
else
|
58
78
|
# :nocov:
|
59
79
|
pg_warn 'clase_modelo is nil'
|
@@ -113,8 +133,10 @@ module PgEngine
|
|
113
133
|
end
|
114
134
|
|
115
135
|
def set_layout
|
116
|
-
if action_name
|
136
|
+
if action_name.in? %w[index archived]
|
117
137
|
'pg_layout/base'
|
138
|
+
elsif action_name == 'show'
|
139
|
+
'pg_layout/show'
|
118
140
|
else
|
119
141
|
'pg_layout/containerized'
|
120
142
|
end
|
@@ -129,10 +151,20 @@ module PgEngine
|
|
129
151
|
pg_respond_buscar
|
130
152
|
end
|
131
153
|
|
154
|
+
def archived
|
155
|
+
add_breadcrumb 'Archivados'
|
156
|
+
|
157
|
+
@index_url = index_url
|
158
|
+
|
159
|
+
@collection = filtros_y_policy(atributos_para_buscar, 'discarded_at desc', archived: true)
|
160
|
+
|
161
|
+
pg_respond_index(archived: true)
|
162
|
+
end
|
163
|
+
|
132
164
|
def index
|
133
165
|
@collection = filtros_y_policy(atributos_para_buscar, default_sort)
|
134
166
|
|
135
|
-
pg_respond_index
|
167
|
+
pg_respond_index(archived: false)
|
136
168
|
end
|
137
169
|
|
138
170
|
def show
|
@@ -186,12 +218,48 @@ module PgEngine
|
|
186
218
|
end
|
187
219
|
|
188
220
|
def destroy
|
189
|
-
pg_respond_destroy(instancia_modelo, params[:
|
221
|
+
pg_respond_destroy(instancia_modelo, params[:land_on])
|
222
|
+
end
|
223
|
+
|
224
|
+
def archive
|
225
|
+
discard_undiscard(:discard)
|
226
|
+
end
|
227
|
+
|
228
|
+
def restore
|
229
|
+
discard_undiscard(:undiscard)
|
190
230
|
end
|
191
231
|
# End public endpoints
|
192
232
|
|
193
233
|
protected
|
194
234
|
|
235
|
+
def discard_undiscard(method)
|
236
|
+
if instancia_modelo.send(method)
|
237
|
+
if accepts_turbo_stream?
|
238
|
+
body = <<~HTML.html_safe
|
239
|
+
<pg-event data-event-name="pg:record-updated" data-reload="true" data-turbo-temporary>
|
240
|
+
</pg-event>
|
241
|
+
HTML
|
242
|
+
render turbo_stream: turbo_stream.append(current_turbo_frame, body)
|
243
|
+
else
|
244
|
+
redirect_to instancia_modelo.decorate.target_object
|
245
|
+
end
|
246
|
+
|
247
|
+
else
|
248
|
+
message = I18n.t('pg_engine.resource_not_updated', model: instancia_modelo.class)
|
249
|
+
if accepts_turbo_stream?
|
250
|
+
flash.now[:alert] = message
|
251
|
+
render turbo_stream: render_turbo_stream_flash_messages, status: :unprocessable_entity
|
252
|
+
else
|
253
|
+
flash[:alert] = message
|
254
|
+
redirect_to instancia_modelo.decorate.target_object
|
255
|
+
end
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
def index_url
|
260
|
+
path_for([pg_namespace, nested_record, clase_modelo])
|
261
|
+
end
|
262
|
+
|
195
263
|
def default_sort
|
196
264
|
'id desc'
|
197
265
|
end
|
@@ -309,10 +377,10 @@ module PgEngine
|
|
309
377
|
end
|
310
378
|
end
|
311
379
|
|
312
|
-
def pg_respond_index
|
380
|
+
def pg_respond_index(archived:)
|
313
381
|
respond_to do |format|
|
314
382
|
format.json { render json: @collection }
|
315
|
-
format.html { render_listing }
|
383
|
+
format.html { render_listing(archived:) }
|
316
384
|
format.xlsx do
|
317
385
|
render xlsx: 'download',
|
318
386
|
filename: "#{clase_modelo.nombre_plural.gsub(' ', '-').downcase}" \
|
@@ -331,12 +399,20 @@ module PgEngine
|
|
331
399
|
end
|
332
400
|
end
|
333
401
|
|
334
|
-
def
|
335
|
-
|
402
|
+
def land_on_url(land_on)
|
403
|
+
case land_on
|
404
|
+
when 'index'
|
405
|
+
index_url
|
406
|
+
else
|
407
|
+
# :nocov:
|
408
|
+
pg_warn "Unrecognized land_on: #{land_on}"
|
409
|
+
instancia_modelo.decorate.target_object
|
410
|
+
# :nocov:
|
411
|
+
end
|
336
412
|
end
|
337
413
|
|
338
414
|
# rubocop:disable Metrics/PerceivedComplexity
|
339
|
-
def pg_respond_destroy(model,
|
415
|
+
def pg_respond_destroy(model, land_on = nil)
|
340
416
|
if destroy_model(model)
|
341
417
|
# FIXME: rename to main
|
342
418
|
if turbo_frame? && current_turbo_frame != 'top'
|
@@ -345,8 +421,10 @@ module PgEngine
|
|
345
421
|
</pg-event>
|
346
422
|
HTML
|
347
423
|
render turbo_stream: turbo_stream.append(current_turbo_frame, body)
|
348
|
-
elsif
|
349
|
-
redirect_to
|
424
|
+
elsif land_on.present?
|
425
|
+
redirect_to land_on_url(land_on),
|
426
|
+
notice: I18n.t('pg_engine.resource_destroyed', model: model.class),
|
427
|
+
status: :see_other
|
350
428
|
elsif accepts_turbo_stream?
|
351
429
|
body = <<~HTML.html_safe
|
352
430
|
<pg-event data-event-name="pg:record-destroyed" data-turbo-temporary>
|
@@ -355,7 +433,8 @@ module PgEngine
|
|
355
433
|
render turbo_stream: turbo_stream.append_all('body', body)
|
356
434
|
else
|
357
435
|
redirect_back(fallback_location: root_path,
|
358
|
-
notice:
|
436
|
+
notice: I18n.t('pg_engine.resource_destroyed', model: model.class),
|
437
|
+
status: 303)
|
359
438
|
end
|
360
439
|
elsif in_modal?
|
361
440
|
|
@@ -372,32 +451,31 @@ module PgEngine
|
|
372
451
|
# rubocop:enable Metrics/PerceivedComplexity
|
373
452
|
|
374
453
|
def destroy_model(model)
|
375
|
-
@error_message = '
|
454
|
+
@error_message = I18n.t('pg_engine.resource_not_destroyed', model: model.class)
|
376
455
|
|
377
456
|
begin
|
378
|
-
|
379
|
-
return true if model.send(destroy_method)
|
457
|
+
return true if model.destroy
|
380
458
|
|
381
459
|
@error_message = model.errors.full_messages.join(', ').presence || @error_message
|
382
460
|
|
383
461
|
false
|
384
462
|
rescue ActiveRecord::InvalidForeignKey => e
|
385
|
-
model_name = t("activerecord.models.#{model.class.name.underscore}")
|
386
|
-
@error_message = "#{model_name} no se pudo borrar porque tiene elementos asociados."
|
387
463
|
pg_warn(e)
|
464
|
+
@error_message = I18n.t('pg_engine.resource_not_destroyed_because_associated', model: model.class)
|
388
465
|
end
|
389
466
|
|
390
467
|
false
|
391
468
|
end
|
392
469
|
|
393
|
-
def render_listing
|
470
|
+
def render_listing(archived:)
|
394
471
|
total = @collection.count
|
395
472
|
current_page = params[:page].presence&.to_i || 1
|
396
473
|
if current_page_size * (current_page - 1) >= total
|
397
474
|
current_page = (total.to_f / current_page_size).ceil
|
398
475
|
end
|
399
476
|
@collection = @collection.page(current_page).per(current_page_size)
|
400
|
-
@records_filtered = default_scope_for_current_model.any? if @collection.empty?
|
477
|
+
@records_filtered = default_scope_for_current_model(archived:).any? if @filtros.present? && @collection.empty?
|
478
|
+
render :index
|
401
479
|
end
|
402
480
|
|
403
481
|
def buscar_instancia
|
@@ -450,19 +528,11 @@ module PgEngine
|
|
450
528
|
clase_modelo.name.underscore
|
451
529
|
end
|
452
530
|
|
453
|
-
def filtros_y_policy(campos, dflt_sort = nil)
|
531
|
+
def filtros_y_policy(campos, dflt_sort = nil, archived: false)
|
454
532
|
@filtros = PgEngine::FiltrosBuilder.new(
|
455
533
|
self, clase_modelo, campos
|
456
534
|
)
|
457
|
-
scope =
|
458
|
-
|
459
|
-
if nested_id.present?
|
460
|
-
scope = scope.where(nested_key => nested_id)
|
461
|
-
scope = scope.undiscarded if scope.respond_to?(:undiscarded)
|
462
|
-
elsif scope.respond_to?(:kept)
|
463
|
-
scope = scope.kept
|
464
|
-
end
|
465
|
-
# Soft deleted
|
535
|
+
scope = default_scope_for_current_model(archived:)
|
466
536
|
|
467
537
|
shared_context = Ransack::Adapters::ActiveRecord::Context.new(scope)
|
468
538
|
@q = clase_modelo.ransack(params[:q], context: shared_context)
|
@@ -471,20 +541,30 @@ module PgEngine
|
|
471
541
|
shared_context.evaluate(@q)
|
472
542
|
end
|
473
543
|
|
474
|
-
def
|
544
|
+
def soft_delete_filter(scope, archived:)
|
545
|
+
return scope unless scope.respond_to?(:discarded)
|
546
|
+
|
547
|
+
if nested_id.present?
|
548
|
+
if archived
|
549
|
+
scope.discarded
|
550
|
+
else
|
551
|
+
scope.undiscarded
|
552
|
+
end
|
553
|
+
elsif archived
|
554
|
+
scope.unkept
|
555
|
+
else
|
556
|
+
scope.kept
|
557
|
+
end
|
558
|
+
end
|
559
|
+
|
560
|
+
def default_scope_for_current_model(archived: false)
|
475
561
|
scope = policy_scope(clase_modelo)
|
476
562
|
|
477
563
|
if nested_id.present?
|
478
564
|
scope = scope.where(nested_key => nested_id)
|
479
|
-
|
480
|
-
# Skip nested discarded check
|
481
|
-
scope = scope.undiscarded if scope.respond_to?(:undiscarded)
|
482
|
-
elsif scope.respond_to?(:kept)
|
483
|
-
scope = scope.kept
|
484
565
|
end
|
485
|
-
# Soft deleted, including nested discarded check
|
486
566
|
|
487
|
-
scope
|
567
|
+
soft_delete_filter(scope, archived:)
|
488
568
|
end
|
489
569
|
end
|
490
570
|
end
|
@@ -10,10 +10,6 @@ module Users
|
|
10
10
|
add_breadcrumb 'Cuentas'
|
11
11
|
self.skip_default_breadcrumb = true
|
12
12
|
|
13
|
-
before_action(only: :index) { authorize Account }
|
14
|
-
|
15
|
-
before_action :set_instancia_modelo, only: %i[new create show edit update destroy]
|
16
|
-
|
17
13
|
# private
|
18
14
|
|
19
15
|
# def atributos_permitidos
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# rubocop:disable Metrics/ClassLength
|
3
4
|
module PgEngine
|
4
5
|
class BaseRecordDecorator < Draper::Decorator
|
5
6
|
include ActionView::Helpers
|
@@ -28,8 +29,7 @@ module PgEngine
|
|
28
29
|
|
29
30
|
def text_for_new
|
30
31
|
klass = object.class
|
31
|
-
|
32
|
-
verb = klass.new.gender == 'f' ? 'Nueva' : 'Nuevo'
|
32
|
+
verb = klass.gender == 'f' ? 'Nueva' : 'Nuevo'
|
33
33
|
"#{verb} #{klass.model_name.human.downcase}"
|
34
34
|
end
|
35
35
|
|
@@ -57,22 +57,50 @@ module PgEngine
|
|
57
57
|
if helpers.using_modal?
|
58
58
|
destroy_link
|
59
59
|
else
|
60
|
-
destroy_link(
|
60
|
+
destroy_link(land_on: :index)
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
64
|
-
def destroy_link(confirm_text: '¿Confirmás que querés borrar el registro?', klass: 'btn-light',
|
64
|
+
def destroy_link(confirm_text: '¿Confirmás que querés borrar el registro?', klass: 'btn-light', land_on: nil)
|
65
65
|
return unless Pundit.policy!(Current.user, object).destroy?
|
66
66
|
|
67
|
-
helpers.content_tag :span, rel: :tooltip, title: 'Eliminar' do
|
68
|
-
helpers.link_to object_url + (
|
67
|
+
helpers.content_tag :span, rel: :tooltip, title: 'Eliminar definitivamente' do
|
68
|
+
helpers.link_to object_url + (land_on.present? ? "?land_on=#{land_on}" : ''),
|
69
69
|
data: { 'turbo-confirm': confirm_text, 'turbo-method': :delete },
|
70
|
-
class: "btn btn-sm #{klass}" do
|
70
|
+
class: "btn btn-sm #{klass} text-danger" do
|
71
71
|
helpers.content_tag :span, nil, class: clase_icono('trash-fill')
|
72
72
|
end
|
73
73
|
end
|
74
74
|
end
|
75
75
|
|
76
|
+
def archive_link(klass: 'btn-light')
|
77
|
+
return unless Pundit.policy!(Current.user, object).archive?
|
78
|
+
|
79
|
+
target_archive = [:archive, pg_namespace, nested_record, object]
|
80
|
+
|
81
|
+
helpers.content_tag :span, rel: :tooltip, title: 'Archivar' do
|
82
|
+
helpers.link_to helpers.url_for(target_archive),
|
83
|
+
data: { 'turbo-method': :post, 'turbo-stream': true },
|
84
|
+
class: "btn btn-sm #{klass}" do
|
85
|
+
helpers.content_tag :span, nil, class: clase_icono('archive-fill')
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def restore_link(klass: 'btn-light')
|
91
|
+
return unless Pundit.policy!(Current.user, object).restore?
|
92
|
+
|
93
|
+
target_archive = [:restore, pg_namespace, nested_record, object]
|
94
|
+
|
95
|
+
helpers.content_tag :span, rel: :tooltip, title: 'Desarchivar' do
|
96
|
+
helpers.link_to helpers.url_for(target_archive),
|
97
|
+
data: { 'turbo-method': :post, 'turbo-stream': true },
|
98
|
+
class: "btn btn-sm #{klass}" do
|
99
|
+
helpers.content_tag(:span, nil, class: clase_icono('arrow-counterclockwise')) + ' Desarchivar'
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
76
104
|
def edit_link(text: ' Modificar', klass: 'btn-warning')
|
77
105
|
return unless Pundit.policy!(Current.user, object).edit?
|
78
106
|
|
@@ -103,14 +131,11 @@ module PgEngine
|
|
103
131
|
end
|
104
132
|
end
|
105
133
|
|
106
|
-
def export_link(url, text: ''
|
134
|
+
def export_link(url, text: '')
|
107
135
|
return unless Pundit.policy!(Current.user, object).export?
|
108
136
|
|
109
|
-
helpers.content_tag :
|
110
|
-
helpers.content_tag
|
111
|
-
class: "btn btn-sm #{klass}", href: url_change_format(url, 'xlsx') do
|
112
|
-
"#{helpers.content_tag(:span, nil, class: clase_icono('file-earmark-excel-fill'))} #{text}".html_safe
|
113
|
-
end
|
137
|
+
helpers.content_tag :a, target: '_blank', class: 'icon-link dropdown-item lh-1', href: url_change_format(url, 'xlsx') do
|
138
|
+
"#{helpers.content_tag(:span, nil, class: clase_icono('file-earmark-excel-fill'))} #{text}".html_safe
|
114
139
|
end
|
115
140
|
end
|
116
141
|
|
@@ -182,3 +207,4 @@ module PgEngine
|
|
182
207
|
end
|
183
208
|
end
|
184
209
|
end
|
210
|
+
# rubocop:enable Metrics/ClassLength
|
@@ -18,13 +18,13 @@ module PgEngine
|
|
18
18
|
sort_field = sort_field.to_s.sub(/_text\z/, '')
|
19
19
|
end
|
20
20
|
|
21
|
+
# Unsuffixed
|
21
22
|
campo = campo.to_s.sub(/_f\z/, '')
|
22
23
|
campo = campo.to_s.sub(/_text\z/, '')
|
23
24
|
|
24
25
|
clase = options[:clase] || @clase_modelo
|
25
|
-
|
26
|
-
|
27
|
-
human_name = clase.human_attribute_name(key, default: dflt)
|
26
|
+
|
27
|
+
human_name = scoped_human_attr_name(clase, campo, 'listado_header')
|
28
28
|
|
29
29
|
if options[:ordenable]
|
30
30
|
if sort_field.is_a? Array
|
@@ -37,6 +37,20 @@ module PgEngine
|
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
|
+
def scoped_human_attr_name(clase, campo, scope)
|
41
|
+
action_key = build_scoped_key(clase, campo, scope, action_name)
|
42
|
+
scope_key = build_scoped_key(clase, campo, scope)
|
43
|
+
|
44
|
+
I18n.t(action_key, default: [scope_key, clase.human_attribute_name(campo)])
|
45
|
+
end
|
46
|
+
|
47
|
+
def build_scoped_key(clase, campo, scope = nil, subscope = nil)
|
48
|
+
campo = "#{campo}/scoped" if scope.present?
|
49
|
+
scope = "#{subscope}/#{scope}" if subscope.present?
|
50
|
+
|
51
|
+
['activerecord.attributes', clase.model_name.i18n_key, campo, scope].compact.join('.').to_sym
|
52
|
+
end
|
53
|
+
|
40
54
|
def default_order(campo)
|
41
55
|
columna = @clase_modelo.columns.find { _1.name == campo.to_s }
|
42
56
|
if columna && columna.type.to_s.include?('date')
|
@@ -5,6 +5,7 @@ module PgEngine
|
|
5
5
|
include ActionView::Helpers
|
6
6
|
include ActionView::Context
|
7
7
|
include PostgresHelper
|
8
|
+
include IndexHelper
|
8
9
|
attr_accessor :controller
|
9
10
|
|
10
11
|
# El orden de los sufijos es importante
|
@@ -140,16 +141,13 @@ module PgEngine
|
|
140
141
|
|
141
142
|
def placeholder_campo(campo)
|
142
143
|
suf = extraer_sufijo(campo)
|
143
|
-
|
144
|
-
dflt = :"activerecord.attributes.#{@clase_modelo.model_name.i18n_key}.#{sin_sufijo(campo)}"
|
145
|
-
human_name = @clase_modelo.human_attribute_name(key, default: dflt)
|
144
|
+
human_name = scoped_human_attr_name(@clase_modelo, sin_sufijo(campo), 'filter')
|
146
145
|
|
147
|
-
ret =
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
end
|
146
|
+
ret = if suf.present?
|
147
|
+
"#{human_name} #{I18n.t(suf, scope: 'ransack.predicates')}"
|
148
|
+
else
|
149
|
+
human_name
|
150
|
+
end
|
153
151
|
|
154
152
|
ret.strip.downcase.tap { _1[0] = _1[0].capitalize }
|
155
153
|
end
|