pg_rails 7.0.1 → 7.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (166) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +6 -4
  3. data/pg_associable/app/assets/css/pg_associable.scss +99 -0
  4. data/pg_associable/app/assets/js/asociable_controller.js +59 -0
  5. data/pg_associable/app/assets/js/asociable_inline_controller.js +141 -0
  6. data/pg_associable/app/assets/js/modal_controller.js +130 -0
  7. data/pg_associable/app/helpers/pg_associable/form_builder_methods.rb +31 -0
  8. data/pg_associable/app/helpers/pg_associable/helpers.rb +19 -0
  9. data/pg_associable/app/inputs/pg_associable/pg_associable_inline_input.rb +39 -0
  10. data/pg_associable/app/inputs/pg_associable/pg_associable_input.rb +41 -0
  11. data/pg_associable/app/views/pg_associable/_resultados.html.slim +9 -0
  12. data/pg_associable/app/views/pg_associable/_resultados_inline.html.slim +12 -0
  13. data/pg_associable/app/views/pg_engine/base/_pg_associable_modal.html.slim +39 -0
  14. data/pg_associable/index.js +7 -0
  15. data/pg_associable/lib/pg_associable/engine.rb +12 -0
  16. data/pg_associable/lib/pg_associable/simple_form_initializer.rb +34 -0
  17. data/pg_associable/lib/pg_associable.rb +5 -0
  18. data/{lib/tasks/pg_rails_tasks.rake → pg_associable/lib/tasks/pg_associable_tasks.rake} +1 -2
  19. data/pg_associable/spec/pg_associable/helpers_spec.rb +24 -0
  20. data/pg_engine/app/assets/stylesheets/pg_rails_b5.scss +74 -0
  21. data/pg_engine/app/controllers/pg_engine/base_controller.rb +82 -0
  22. data/pg_engine/app/controllers/pg_engine/devise_controller.rb +9 -0
  23. data/pg_engine/app/controllers/pg_engine/require_sign_in.rb +9 -0
  24. data/pg_engine/app/controllers/pg_engine/resource_helper.rb +289 -0
  25. data/{app/decorators/pg_rails → pg_engine/app/decorators/pg_engine}/base_decorator.rb +21 -23
  26. data/pg_engine/app/helpers/pg_engine/flash_helper.rb +28 -0
  27. data/pg_engine/app/helpers/pg_engine/form_helper.rb +33 -0
  28. data/pg_engine/app/helpers/pg_engine/index_helper.rb +42 -0
  29. data/{app/helpers/pg_rails → pg_engine/app/helpers/pg_engine}/postgres_helper.rb +1 -1
  30. data/{app/helpers/pg_rails → pg_engine/app/helpers/pg_engine}/print_helper.rb +15 -31
  31. data/pg_engine/app/helpers/pg_engine/route_helper.rb +43 -0
  32. data/pg_engine/app/inputs/pg_engine/fecha_input.rb +20 -0
  33. data/{app/lib/pg_rails → pg_engine/app/lib/pg_engine}/filtros_builder.rb +16 -17
  34. data/pg_engine/app/lib/pg_form_builder.rb +22 -0
  35. data/pg_engine/app/models/pg_engine/base_record.rb +63 -0
  36. data/{app/policies/pg_rails → pg_engine/app/policies/pg_engine}/application_policy.rb +2 -2
  37. data/pg_engine/app/views/pg_engine/base/download.xlsx.axlsx +14 -0
  38. data/pg_engine/app/views/pg_engine/base/index.html.slim +51 -0
  39. data/pg_engine/config/locales/es.yml +48 -0
  40. data/pg_engine/config/simple_form/simple_form.rb +178 -0
  41. data/pg_engine/config/simple_form/simple_form_bootstrap.rb +371 -0
  42. data/{lib/pg_rails → pg_engine/lib/pg_engine}/configuracion.rb +3 -1
  43. data/pg_engine/lib/pg_engine/engine.rb +57 -0
  44. data/pg_engine/lib/pg_engine/route_helpers.rb +12 -0
  45. data/pg_engine/lib/pg_engine/utils/pg_logger.rb +44 -0
  46. data/{lib/pg_rails.rb → pg_engine/lib/pg_engine.rb} +6 -4
  47. data/{lib → pg_engine/lib}/tasks/auto_anotar_modelos.rake +1 -1
  48. data/pg_engine/lib/templates/activeadmin/audits.rb +53 -0
  49. data/pg_engine/lib/templates/activeadmin/users.rb +54 -0
  50. data/pg_layout/app/assets/stylesheets/sidebar.scss +110 -0
  51. data/pg_layout/app/javascript/cookies.js +23 -0
  52. data/pg_layout/app/javascript/navbar_controller.js +10 -0
  53. data/pg_layout/app/lib/navbar.rb +61 -0
  54. data/pg_layout/app/views/devise/confirmations/new.html.erb +20 -0
  55. data/pg_layout/app/views/devise/mailer/confirmation_instructions.html.erb +5 -0
  56. data/pg_layout/app/views/devise/mailer/email_changed.html.erb +7 -0
  57. data/pg_layout/app/views/devise/mailer/password_change.html.erb +3 -0
  58. data/pg_layout/app/views/devise/mailer/reset_password_instructions.html.erb +8 -0
  59. data/pg_layout/app/views/devise/mailer/unlock_instructions.html.erb +7 -0
  60. data/pg_layout/app/views/devise/passwords/edit.html.erb +27 -0
  61. data/pg_layout/app/views/devise/passwords/new.html.erb +18 -0
  62. data/pg_layout/app/views/devise/registrations/edit.html.erb +35 -0
  63. data/pg_layout/app/views/devise/registrations/new.html.erb +25 -0
  64. data/pg_layout/app/views/devise/sessions/new.html.erb +20 -0
  65. data/pg_layout/app/views/devise/shared/_error_messages.html.erb +15 -0
  66. data/pg_layout/app/views/devise/shared/_links.html.erb +25 -0
  67. data/pg_layout/app/views/devise/unlocks/new.html.erb +19 -0
  68. data/pg_layout/app/views/kaminari/_first_page.html.slim +3 -0
  69. data/pg_layout/app/views/kaminari/_gap.html.slim +2 -0
  70. data/pg_layout/app/views/kaminari/_last_page.html.slim +3 -0
  71. data/pg_layout/app/views/kaminari/_next_page.html.slim +3 -0
  72. data/pg_layout/app/views/kaminari/_page.html.slim +6 -0
  73. data/pg_layout/app/views/kaminari/_paginator.html.slim +12 -0
  74. data/pg_layout/app/views/kaminari/_prev_page.html.slim +3 -0
  75. data/pg_layout/app/views/layouts/pg_layout/devise.html.slim +24 -0
  76. data/pg_layout/app/views/layouts/pg_layout/layout.html.slim +31 -0
  77. data/pg_layout/app/views/pg_layout/_flash.html.slim +10 -0
  78. data/pg_layout/app/views/pg_layout/_navbar.html.erb +35 -0
  79. data/pg_layout/app/views/pg_layout/_sidebar.html.erb +42 -0
  80. data/pg_layout/index.js +35 -0
  81. data/pg_layout/lib/pg_layout/engine.rb +7 -0
  82. data/pg_layout/lib/pg_layout.rb +9 -0
  83. data/pg_rails/js/index.js +2 -0
  84. data/pg_rails/lib/pg_rails.rb +7 -0
  85. data/{lib/pg_rails → pg_rails/lib}/version.rb +1 -1
  86. data/pg_rails/scss/pg_rails.scss +3 -0
  87. data/pg_scaffold/lib/generators/pg_active_record/model/model_generator.rb +34 -0
  88. data/pg_scaffold/lib/generators/pg_active_record/model/templates/admin.rb +19 -0
  89. data/pg_scaffold/lib/generators/pg_active_record/model/templates/create_table_migration.rb.tt +46 -0
  90. data/pg_scaffold/lib/generators/pg_active_record/model/templates/migration.rb.tt +48 -0
  91. data/pg_scaffold/lib/generators/pg_active_record/model/templates/model.rb +46 -0
  92. data/pg_scaffold/lib/generators/pg_active_record/model/templates/module.rb +9 -0
  93. data/pg_scaffold/lib/generators/pg_decorator/USAGE +8 -0
  94. data/pg_scaffold/lib/generators/pg_decorator/pg_decorator_generator.rb +31 -0
  95. data/pg_scaffold/lib/generators/pg_decorator/templates/decorator.rb +22 -0
  96. data/pg_scaffold/lib/generators/pg_factory_bot/model/model_generator.rb +95 -0
  97. data/pg_scaffold/lib/generators/pg_factory_bot/model/templates/factories.erb +14 -0
  98. data/pg_scaffold/lib/generators/pg_pundit/USAGE +8 -0
  99. data/pg_scaffold/lib/generators/pg_pundit/pg_pundit_generator.rb +21 -0
  100. data/pg_scaffold/lib/generators/pg_pundit/templates/policy.rb +37 -0
  101. data/pg_scaffold/lib/generators/pg_rails/instalar/USAGE +8 -0
  102. data/pg_scaffold/lib/generators/pg_rails/instalar/instalar_generator.rb +17 -0
  103. data/pg_scaffold/lib/generators/pg_rails/instalar/templates/pg_rails.rb +10 -0
  104. data/pg_scaffold/lib/generators/pg_resource_route/pg_resource_route_generator.rb +27 -0
  105. data/pg_scaffold/lib/generators/pg_rspec/model/model_generator.rb +30 -0
  106. data/pg_scaffold/lib/generators/pg_rspec/model/templates/model_spec.rb +15 -0
  107. data/pg_scaffold/lib/generators/pg_rspec/scaffold/scaffold_generator.rb +43 -0
  108. data/pg_scaffold/lib/generators/pg_rspec/scaffold/templates/api_controller_spec.rb +167 -0
  109. data/pg_scaffold/lib/generators/pg_rspec/scaffold/templates/controller_spec.rb +276 -0
  110. data/pg_scaffold/lib/generators/pg_rspec/scaffold/templates/edit_spec.rb +34 -0
  111. data/pg_scaffold/lib/generators/pg_rspec/scaffold/templates/index_spec.rb +28 -0
  112. data/pg_scaffold/lib/generators/pg_rspec/scaffold/templates/new_spec.rb +34 -0
  113. data/pg_scaffold/lib/generators/pg_rspec/scaffold/templates/routing_spec.rb +50 -0
  114. data/pg_scaffold/lib/generators/pg_rspec/scaffold/templates/show_spec.rb +26 -0
  115. data/pg_scaffold/lib/generators/pg_scaffold/USAGE +8 -0
  116. data/pg_scaffold/lib/generators/pg_scaffold/pg_scaffold_generator.rb +81 -0
  117. data/pg_scaffold/lib/generators/pg_scaffold/templates/controller.rb +37 -0
  118. data/pg_scaffold/lib/generators/pg_slim/USAGE +8 -0
  119. data/pg_scaffold/lib/generators/pg_slim/pg_slim_generator.rb +31 -0
  120. data/pg_scaffold/lib/generators/pg_slim/templates/_form.html.slim +12 -0
  121. data/pg_scaffold/lib/generators/pg_slim/templates/download.xlsx.axlsx +14 -0
  122. data/pg_scaffold/lib/generators/pg_slim/templates/edit.html.slim +5 -0
  123. data/pg_scaffold/lib/generators/pg_slim/templates/index.html.slim +51 -0
  124. data/pg_scaffold/lib/generators/pg_slim/templates/new.html.slim +5 -0
  125. data/pg_scaffold/lib/generators/pg_slim/templates/partial.html.slim +1 -0
  126. data/pg_scaffold/lib/generators/pg_slim/templates/show.html.slim +38 -0
  127. data/pg_scaffold/lib/pg_scaffold/monkey_patches/mejoras_a_named_base.rb +37 -0
  128. data/pg_scaffold/lib/pg_scaffold/monkey_patches/mejoras_de_atributos.rb +116 -0
  129. data/pg_scaffold/lib/pg_scaffold/railtie.rb +16 -0
  130. data/pg_scaffold/lib/pg_scaffold.rb +4 -0
  131. data/pg_scaffold/spec/generators_spec.rb +55 -0
  132. metadata +138 -48
  133. data/Rakefile +0 -36
  134. data/app/assets/javascripts/pg_rails/asociacion_creable.js +0 -85
  135. data/app/assets/javascripts/pg_rails/best_in_place_datepicker.js +0 -58
  136. data/app/assets/javascripts/pg_rails/librerias.js +0 -13
  137. data/app/assets/javascripts/pg_rails/librerias_b3.js +0 -14
  138. data/app/assets/javascripts/pg_rails/validaciones.js +0 -44
  139. data/app/assets/javascripts/pg_rails.js +0 -318
  140. data/app/assets/stylesheets/pg_rails/librerias.scss +0 -5
  141. data/app/assets/stylesheets/pg_rails/pg_chosen.scss +0 -29
  142. data/app/assets/stylesheets/pg_rails/pg_rails.scss +0 -199
  143. data/app/assets/stylesheets/pg_rails_b3.scss +0 -10
  144. data/app/assets/stylesheets/pg_rails_b4.scss +0 -12
  145. data/app/assets/stylesheets/pg_rails_b5.scss +0 -1
  146. data/app/controllers/pg_rails/application_controller.rb +0 -316
  147. data/app/controllers/pg_rails/editar_en_lugar_controller.rb +0 -24
  148. data/app/helpers/pg_rails/editar_en_lugar_helper.rb +0 -106
  149. data/app/helpers/pg_rails/form_helper.rb +0 -25
  150. data/app/inputs/pg_rails/asociacion_creable_input.rb +0 -72
  151. data/app/inputs/pg_rails/fecha_input.rb +0 -20
  152. data/app/inputs/pg_rails/selects_dependientes_input.rb +0 -9
  153. data/app/lib/pg_form_builder.rb +0 -31
  154. data/app/models/pg_rails/application_record.rb +0 -51
  155. data/app/views/application/_abrir_modal.js.erb +0 -14
  156. data/app/views/application/_actualizar_smart_listing.html.slim +0 -3
  157. data/app/views/application/_cerrar_modal.js.erb +0 -8
  158. data/app/views/application/_modal_ajax_form.js.erb +0 -7
  159. data/config/brakeman.ignore +0 -42
  160. data/config/locales/es.yml +0 -17
  161. data/config/routes.rb +0 -3
  162. data/config/spring.rb +0 -1
  163. data/lib/pg_rails/engine.rb +0 -42
  164. data/lib/pg_rails/simple_form/initializer.rb +0 -583
  165. data/lib/pg_rails/utils/logueador.rb +0 -39
  166. /data/{lib/pg_rails → pg_engine/lib/pg_engine}/core_ext.rb +0 -0
@@ -0,0 +1,34 @@
1
+ SimpleForm.setup do |config|
2
+ config.wrappers :pg_associable, tag: 'div', class: 'pg_associable mb-3', html: { data: { controller: 'asociable', 'asociable-modal-outlet': '.modal' } },
3
+ error_class: 'form-group-invalid', valid_class: 'form-group-valid' do |b|
4
+ b.use :html5
5
+ b.optional :readonly
6
+ b.use :label, class: 'form-control-label'
7
+ b.use :hidden_input
8
+ b.wrapper tag: 'div', class: 'position-relative' do |ba|
9
+ ba.use :input, class: 'form-control', disabled: true, placeholder: 'Clic para seleccionar...',
10
+ error_class: 'is-invalid'
11
+ ba.use :pencil
12
+ ba.use :modal_link
13
+ ba.use :limpiar
14
+ end
15
+ b.use :full_error, wrap_with: { tag: 'div', class: 'invalid-feedback d-block' }
16
+ b.use :hint, wrap_with: { tag: 'small', class: 'form-text text-muted' }
17
+ end
18
+
19
+ config.wrappers :pg_associable_inline, tag: 'div', class: 'pg_associable_inline mb-3', html: { data: { controller: 'asociable_inline' } },
20
+ error_class: 'form-group-invalid', valid_class: 'form-group-valid' do |b|
21
+ b.use :html5
22
+ b.optional :readonly
23
+ b.use :label, class: 'form-control-label'
24
+ b.use :hidden_input
25
+ b.wrapper tag: 'div', class: 'search-box position-relative' do |ba|
26
+ ba.use :search_form, error_class: 'is-invalid'
27
+ ba.use :limpiar
28
+ ba.use :pencil
29
+ # ba.use :input, class: 'form-control', placeholder: 'Buscar...'
30
+ end
31
+ b.use :full_error, wrap_with: { tag: 'div', class: 'invalid-feedback d-block' }
32
+ b.use :hint, wrap_with: { tag: 'small', class: 'form-text text-muted' }
33
+ end
34
+ end
@@ -0,0 +1,5 @@
1
+ require_relative 'pg_associable/engine'
2
+
3
+ module PgAssociable
4
+ # Your code goes here...
5
+ end
@@ -1,5 +1,4 @@
1
- # frozen_string_literal: true
2
1
  # desc "Explaining what the task does"
3
- # task :pg_rails do
2
+ # task :pg_associable do
4
3
  # # Task goes here
5
4
  # end
@@ -0,0 +1,24 @@
1
+ require 'rails_helper'
2
+
3
+ describe PgAssociable::Helpers do
4
+ describe '#pg_respond_buscar' do
5
+ let(:user) { create :user }
6
+ let(:ctrl) do
7
+ clazz = Class.new(PgEngine::BaseController)
8
+ clazz.new
9
+ end
10
+ let!(:cosa) { create :cosa }
11
+
12
+ before do
13
+ allow(ctrl).to receive_messages(current_user: user, params: { id: 123, query: cosa.id })
14
+ allow(ctrl).to receive(:render)
15
+ ctrl.instance_variable_set(:@clase_modelo, Cosa)
16
+ end
17
+
18
+ it do
19
+ ctrl.pg_respond_buscar
20
+ cosas = ctrl.instance_variable_get(:@collection)
21
+ expect(cosas).to eq [cosa]
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,74 @@
1
+ @use 'sass:color';
2
+
3
+ :root,
4
+ [data-bs-theme=light] {
5
+ --bs-form-invalid-color: #b50000;
6
+ --bs-form-invalid-border-color: #b50000;
7
+ }
8
+
9
+
10
+ // FORMS
11
+ // .pg-form {
12
+ // max-width: 300px;
13
+
14
+ input[disabled] {
15
+ background-color: #e9e9ed;
16
+ color: black;
17
+ }
18
+
19
+ .form-control,
20
+ .form-select {
21
+ width: 100%;
22
+ height: 35px;
23
+ border: 1px solid #a7b7bb;
24
+ border-radius: 3px;
25
+
26
+ &.form-control-sm,
27
+ &.form-select-sm {
28
+ height: 29px;
29
+ }
30
+
31
+ &.is-invalid {
32
+ background-image: none!important; /* override bootstrap forms */
33
+ padding-right: 0; /* override bootstrap forms */
34
+ }
35
+
36
+ &:focus, &:focus-visible {
37
+ outline: 1px solid color.adjust(#a7b7bb, $saturation: +30%);
38
+ }
39
+ }
40
+ select[multiple] {
41
+ height: inherit;
42
+ }
43
+ .form-control:focus {
44
+ box-shadow: none!important; /* override bootstrap forms */
45
+ }
46
+
47
+ input[type=date] {
48
+ max-width: 170px;
49
+ }
50
+ // }
51
+
52
+ // LISTADOS
53
+ .listado {
54
+ td, th {
55
+ padding: 0.25rem 1rem;
56
+ }
57
+ }
58
+ .listado .btn-sm {
59
+ min-width: 25px;
60
+ height: 25px;
61
+ padding: 1px;
62
+ margin-right: 4px;
63
+ }
64
+
65
+ // FILTROS
66
+ .filter {
67
+ display: inline-block;
68
+ vertical-align: top;
69
+ min-width: 200px;
70
+
71
+ .input-group {
72
+ width: 230px;
73
+ }
74
+ }
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PgEngine
4
+ # rubocop:disable Rails/ApplicationController
5
+ class BaseController < ActionController::Base
6
+ # rubocop:enable Rails/ApplicationController
7
+ include Pundit::Authorization
8
+ include PrintHelper
9
+ include PostgresHelper
10
+ include FlashHelper
11
+ include RouteHelper
12
+ include PgAssociable::Helpers
13
+
14
+ protect_from_forgery with: :exception
15
+
16
+ rescue_from PrintHelper::FechaInvalidaError, with: :fecha_invalida
17
+ rescue_from Pundit::NotAuthorizedError, with: :not_authorized
18
+
19
+ helper_method :mobile_device?
20
+
21
+ layout 'pg_layout/layout'
22
+
23
+ # Los flash_types resultantes serían:
24
+ # [:alert, :notice, :warning, :success]
25
+ add_flash_types :warning, :success
26
+
27
+ before_action do
28
+ @breakpoint_navbar_expand = 'md'
29
+ @navbar_opened_class = if cookies[:navbar_expand] == 'false' || !user_signed_in?
30
+ ''
31
+ else
32
+ 'opened'
33
+ end
34
+ @navbar = Navbar.new(current_user)
35
+ end
36
+
37
+ def mobile_device?
38
+ request.user_agent =~ /Mobile|webOS/
39
+ end
40
+
41
+ protected
42
+
43
+ def default_url_options(options = {})
44
+ if Rails.env.production?
45
+ options.merge(protocol: 'https')
46
+ else
47
+ options
48
+ end
49
+ end
50
+
51
+ def fecha_invalida
52
+ respond_to do |format|
53
+ format.json do
54
+ render json: { error: 'Formato de fecha inválido' },
55
+ status: :unprocessable_entity
56
+ end
57
+ format.html { go_back('Formato de fecha inválido') }
58
+ end
59
+ end
60
+
61
+ def not_authorized
62
+ respond_to do |format|
63
+ format.json do
64
+ render json: { error: 'Not authorized' },
65
+ status: :unprocessable_entity
66
+ end
67
+ format.html do
68
+ if request.path == root_path
69
+ render plain: 'Not authorized'
70
+ else
71
+ go_back('Not authorized')
72
+ end
73
+ end
74
+ end
75
+ end
76
+
77
+ def go_back(message)
78
+ flash[:alert] = message
79
+ redirect_back fallback_location: root_path
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,9 @@
1
+ module PgEngine
2
+ class DeviseController < ApplicationController
3
+ layout 'pg_layout/devise'
4
+
5
+ before_action do
6
+ render(layout: 'pg_layout/layout') if controller_name == 'registrations' && action_name == 'edit'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PgEngine
4
+ module RequireSignIn
5
+ def self.included(clazz)
6
+ clazz.before_action :authenticate_user!
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,289 @@
1
+ module PgEngine
2
+ module ResourceHelper
3
+ def self.included(clazz)
4
+ clazz.before_action :authenticate_user!
5
+ clazz.helper_method :atributos_para_listar
6
+ clazz.helper_method :atributos_para_mostrar
7
+ clazz.helper_method :current_page_size
8
+ clazz.helper_method :any_filter?
9
+ end
10
+
11
+ # Public endpoints
12
+ def abrir_modal
13
+ pg_respond_abrir_modal
14
+ end
15
+
16
+ def buscar
17
+ pg_respond_buscar
18
+ end
19
+
20
+ def index
21
+ @collection = filtros_y_policy atributos_para_buscar
22
+ @collection = sort_collection(@collection)
23
+ pg_respond_index
24
+ end
25
+
26
+ def show
27
+ add_breadcrumb instancia_modelo, instancia_modelo.target_object
28
+
29
+ pg_respond_show
30
+ end
31
+
32
+ def new
33
+ add_breadcrumb "Crear #{@clase_modelo.nombre_singular.downcase}"
34
+ end
35
+
36
+ def edit
37
+ add_breadcrumb instancia_modelo, instancia_modelo.target_object
38
+ add_breadcrumb 'Editando'
39
+ end
40
+
41
+ def create
42
+ pg_respond_create
43
+ end
44
+
45
+ def update
46
+ pg_respond_update
47
+ end
48
+
49
+ def destroy
50
+ url = namespaced_path(@clase_modelo)
51
+ pg_respond_destroy(instancia_modelo, url)
52
+ end
53
+ # End public endpoints
54
+
55
+ protected
56
+
57
+ def any_filter?
58
+ params.keys.reject { |a| a.in? %w[controller action page page_size order_by order_direction] }.any?
59
+ end
60
+
61
+ def current_page_size
62
+ if params[:page_size].present?
63
+ session[:page_size] = params[:page_size]
64
+ params[:page_size].to_i
65
+ else
66
+ default_page_size
67
+ end
68
+ end
69
+
70
+ def default_page_size
71
+ session[:page_size].present? ? session[:page_size].to_i : 10
72
+ end
73
+
74
+ def pg_respond_update(object: nil)
75
+ object ||= instancia_modelo
76
+ respond_to do |format|
77
+ if (@saved = object.save)
78
+ format.html { redirect_to object.decorate.target_object }
79
+ format.json { render json: object.decorate }
80
+ else
81
+ format.html { render :edit, status: :unprocessable_entity }
82
+ format.json { render json: object.errors, status: :unprocessable_entity }
83
+ end
84
+ end
85
+ end
86
+
87
+ def pg_respond_create(object: nil)
88
+ object ||= instancia_modelo
89
+ respond_to do |format|
90
+ if (@saved = object.save)
91
+ if params[:asociable]
92
+ format.turbo_stream do
93
+ render turbo_stream:
94
+ turbo_stream.update('pg-associable-form', <<~HTML
95
+ <div data-modal-target="response" data-response='#{object.decorate.to_json}'></div>
96
+ HTML
97
+ )
98
+ end
99
+ end
100
+ format.html do
101
+ if params[:save_and_next] == 'true'
102
+ new_path = "#{url_for(@clase_modelo)}/new"
103
+ redirect_to new_path, notice: "#{@clase_modelo.nombre_singular} creado."
104
+ else
105
+ redirect_to object.decorate.target_object
106
+ end
107
+ end
108
+ format.json { render json: object.decorate }
109
+ else
110
+ if params[:asociable]
111
+ format.turbo_stream do
112
+ render turbo_stream:
113
+ turbo_stream.update('pg-associable-form', partial: 'form', locals: { asociable: true })
114
+ end
115
+ end
116
+ format.html { render :new, status: :unprocessable_entity }
117
+ format.json { render json: object.errors.full_messages, status: :unprocessable_entity }
118
+ end
119
+ end
120
+ end
121
+
122
+ def pg_respond_index
123
+ respond_to do |format|
124
+ format.json { render json: @collection }
125
+ format.html { render_listing }
126
+ format.xlsx do
127
+ render xlsx: 'download',
128
+ filename: "#{@clase_modelo.nombre_plural.gsub(' ', '-').downcase}" \
129
+ "-#{Time.zone.now.strftime('%Y-%m-%d-%H.%M.%S')}.xlsx"
130
+ end
131
+ end
132
+ end
133
+
134
+ def pg_respond_show(object = nil)
135
+ respond_to do |format|
136
+ format.json { render json: object || instancia_modelo }
137
+ format.html
138
+ end
139
+ end
140
+
141
+ def pg_respond_destroy(model, redirect_url = nil)
142
+ if destroy_model(model)
143
+ respond_to do |format|
144
+ format.html do
145
+ if redirect_url.present?
146
+ redirect_to redirect_url, notice: 'Elemento borrado.', status: :see_other
147
+ else
148
+ redirect_back(fallback_location: root_path, notice: 'Elemento borrado.', status: 303)
149
+ end
150
+ end
151
+ format.json { head :no_content }
152
+ end
153
+ else
154
+ respond_to do |format|
155
+ format.html do
156
+ if model.respond_to?(:associated_elements) && model.associated_elements.present?
157
+ @model = model
158
+ render destroy_error_details_view
159
+ else
160
+ flash[:alert] = @error_message
161
+ # if redirect_url.present?
162
+ # redirect_to redirect_url
163
+ # else
164
+ redirect_back(fallback_location: root_path, status: 303)
165
+ # end
166
+ end
167
+ end
168
+ format.json { render json: { error: @error_message }, status: :unprocessable_entity }
169
+ end
170
+ end
171
+ end
172
+
173
+ # TODO: crear esta vista en pg_rails
174
+ def destroy_error_details_view
175
+ 'destroy_error_details'
176
+ end
177
+
178
+ def destroy_model(model)
179
+ @error_message = 'No se pudo eliminar el registro'
180
+ begin
181
+ destroy_method = model.respond_to?(:discard) ? :discard : :destroy
182
+ return true if model.send(destroy_method)
183
+
184
+ @error_message = model.errors.full_messages.join(', ')
185
+ false
186
+ rescue ActiveRecord::InvalidForeignKey => e
187
+ # class_name = /from table \"(?<table_name>[\p{L}_]*)\"/.match(e.message)[:table_name].singularize.camelcase
188
+ # # pk_id = /from table \"(?<pk_id>[\p{L}_]*)\"/.match(e.message)[:pk_id].singularize.camelcase
189
+ # clazz = Object.const_get class_name
190
+ # objects = clazz.where(model.class.table_name.singularize => model)
191
+ model_name = t("activerecord.models.#{model.class.name.underscore}")
192
+ @error_message = "#{model_name} no se pudo borrar porque tiene elementos asociados."
193
+ logger.debug e.message
194
+ end
195
+ false
196
+ end
197
+
198
+ def render_listing
199
+ @collection = @collection.page(params[:page]).per(current_page_size)
200
+ end
201
+
202
+ def buscar_instancia
203
+ if Object.const_defined?('FriendlyId') && @clase_modelo.is_a?(FriendlyId)
204
+ @clase_modelo.friendly.find(params[:id])
205
+ else
206
+ @clase_modelo.find(params[:id])
207
+ end
208
+ end
209
+
210
+ def set_instancia_modelo
211
+ if action_name.in? %w[new create]
212
+ self.instancia_modelo = @clase_modelo.new(modelo_params)
213
+ else
214
+ self.instancia_modelo = buscar_instancia
215
+
216
+ instancia_modelo.assign_attributes(modelo_params) if action_name.in? %w[update]
217
+ end
218
+
219
+ instancia_modelo.current_user = send(PgEngine.configuracion.current_user_method)
220
+
221
+ authorize instancia_modelo
222
+
223
+ # TODO: problema en create y update cuando falla la validacion
224
+ self.instancia_modelo = instancia_modelo.decorate if action_name.in? %w[show edit new]
225
+ end
226
+
227
+ def instancia_modelo=(val)
228
+ instance_variable_set(:"@#{nombre_modelo}", val)
229
+ end
230
+
231
+ def instancia_modelo
232
+ instance_variable_get(:"@#{nombre_modelo}")
233
+ end
234
+
235
+ def modelo_params
236
+ if action_name == 'new'
237
+ params.permit(atributos_permitidos)
238
+ else
239
+ params.require(nombre_modelo).permit(atributos_permitidos)
240
+ end
241
+ end
242
+
243
+ def nombre_modelo
244
+ @clase_modelo.name.underscore
245
+ end
246
+
247
+ def clase_modelo
248
+ # agarro la variable o intento con el nombre del controller
249
+ @clase_modelo ||= self.class.name.singularize.gsub('Controller', '').constantize
250
+ end
251
+
252
+ def filtros_y_policy(campos)
253
+ @filtros = PgEngine::FiltrosBuilder.new(
254
+ self, clase_modelo, campos
255
+ )
256
+ scope = policy_scope(clase_modelo)
257
+
258
+ @filtros.filtrar(scope)
259
+ end
260
+
261
+ def do_sort(scope, field, direction)
262
+ unless scope.model.column_names.include? field.to_s
263
+ PgLogger.warning("No existe el campo \"#{field}\"")
264
+ return scope
265
+ end
266
+ scope = scope.order(field => direction)
267
+ instance_variable_set(:@field, field)
268
+ instance_variable_set(:@direction, direction)
269
+ scope
270
+ rescue ArgumentError => e
271
+ PgLogger.warning(e.to_s)
272
+ scope
273
+ end
274
+
275
+ def sort_collection(scope, options = {})
276
+ if params[:order_by].present?
277
+ field = params[:order_by]
278
+ direction = params[:order_direction]
279
+ do_sort(scope, field, direction)
280
+ elsif options[:default].present?
281
+ field = options[:default].first[0]
282
+ direction = options[:default].first[1]
283
+ do_sort(scope, field, direction)
284
+ else
285
+ scope
286
+ end
287
+ end
288
+ end
289
+ end
@@ -1,10 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module PgRails
3
+ module PgEngine
4
4
  class BaseDecorator < Draper::Decorator
5
5
  include ActionView::Helpers
6
6
  include PrintHelper
7
7
  include FormHelper
8
+ include RouteHelper
8
9
  include Pundit::Authorization
9
10
 
10
11
  attr_accessor :output_buffer
@@ -15,7 +16,7 @@ module PgRails
15
16
  object.as_json.tap { |o| o[:to_s] = to_s }
16
17
  end
17
18
 
18
- # def method_missing(method_name, *args, &block) # rubocop:disable Style/MissingRespondToMissing
19
+ # def method_missing(method_name, *args, &block)
19
20
  # valor = object.attributes[method_name.to_s]
20
21
  # return super unless valor.present?
21
22
 
@@ -29,7 +30,7 @@ module PgRails
29
30
  # end
30
31
 
31
32
  def destroy_link(message = '¿Estás seguro?')
32
- return unless Pundit.policy!(helpers.send(PgRails.configuracion.current_user_method), object).destroy?
33
+ return unless Pundit.policy!(helpers.send(PgEngine.configuracion.current_user_method), object).destroy?
33
34
 
34
35
  helpers.content_tag :span, rel: :tooltip, title: 'Eliminar' do
35
36
  helpers.link_to object_url, data: { 'turbo-confirm': message, 'turbo-method': :delete },
@@ -40,43 +41,44 @@ module PgRails
40
41
  end
41
42
 
42
43
  def edit_link(texto = '')
43
- return unless Pundit.policy!(helpers.send(PgRails.configuracion.current_user_method), object).edit?
44
+ return unless Pundit.policy!(helpers.send(PgEngine.configuracion.current_user_method), object).edit?
44
45
 
45
46
  helpers.content_tag :span, rel: :tooltip, title: 'Editar' do
46
47
  helpers.link_to edit_object_url, data: { turbo_frame: :main },
47
- class: "btn #{_config.clase_botones_chicos} btn-#{_config.boton_edit}" do
48
+ class: "btn #{_config.clase_botones_chicos} btn-#{_config.boton_edit}" do
48
49
  helpers.content_tag(:span, nil, class: clase_icono(_config.icono_edit).to_s) + texto
49
50
  end
50
51
  end
51
52
  end
52
53
 
53
54
  def show_link(texto = '')
54
- return unless Pundit.policy!(helpers.send(PgRails.configuracion.current_user_method), object).show?
55
+ return unless Pundit.policy!(helpers.send(PgEngine.configuracion.current_user_method), object).show?
55
56
 
56
57
  helpers.content_tag :span, rel: :tooltip, title: 'Ver' do
57
58
  helpers.link_to object_url, data: { turbo_frame: :main },
58
- class: "btn #{_config.clase_botones_chicos} btn-#{_config.boton_show}" do
59
+ class: "btn #{_config.clase_botones_chicos} btn-#{_config.boton_show}" do
59
60
  helpers.content_tag(:span, nil, class: clase_icono(_config.icono_show).to_s) + texto
60
61
  end
61
62
  end
62
63
  end
63
64
 
64
65
  def export_link(url, texto = '')
65
- return unless Pundit.policy!(helpers.send(PgRails.configuracion.current_user_method), object).export?
66
+ return unless Pundit.policy!(helpers.send(PgEngine.configuracion.current_user_method), object).export?
66
67
 
67
68
  helpers.content_tag :span, rel: :tooltip, title: 'Exportar' do
68
69
  helpers.content_tag :a, target: '_blank',
69
- class: "btn #{_config.clase_botones_chicos} btn-#{_config.boton_export}", href: url_change_format(url) do
70
+ class: "btn #{_config.clase_botones_chicos} btn-#{_config.boton_export}", href: url_change_format(url, 'xlsx') do
70
71
  "#{helpers.content_tag(:span, nil, class: clase_icono('file-earmark-excel-fill'))} #{texto}".html_safe
71
72
  end
72
73
  end
73
74
  end
74
75
 
75
76
  def new_link(options = {})
76
- return unless Pundit.policy!(helpers.send(PgRails.configuracion.current_user_method), object).new?
77
+ return unless Pundit.policy!(helpers.send(PgEngine.configuracion.current_user_method), object).new?
77
78
 
78
79
  helpers.content_tag :span, rel: :tooltip, title: 'Crear' do
79
- helpers.link_to new_object_url, class: "btn #{_config.clase_botones_chicos} btn-primary", remote: options[:remote] do
80
+ helpers.link_to new_object_url, class: "btn #{_config.clase_botones_chicos} btn-primary",
81
+ remote: options[:remote] do
80
82
  helpers.content_tag(:span, nil,
81
83
  class: clase_icono('plus').to_s) + "<span class='d-none d-sm-inline'> Crear #{object.class.nombre_singular.downcase}</span>".html_safe
82
84
  end
@@ -96,25 +98,21 @@ module PgRails
96
98
  end
97
99
 
98
100
  def target_object
99
- default_module.present? ? [default_module, object] : object
101
+ pg_namespace.present? ? [pg_namespace, object] : object
100
102
  end
101
103
 
102
104
  def target_index
103
- default_module.present? ? [default_module, object.class] : object.class
104
- end
105
-
106
- def default_module
107
- nil
105
+ pg_namespace.present? ? [pg_namespace, object.class] : object.class
108
106
  end
109
107
 
110
108
  private
111
109
 
112
- def _config
113
- PgRails.configuracion
114
- end
110
+ def _config
111
+ PgEngine.configuracion
112
+ end
115
113
 
116
- def clase_icono(icono)
117
- "#{_config.sistema_iconos} #{_config.sistema_iconos}-#{icono}"
118
- end
114
+ def clase_icono(icono)
115
+ "#{_config.sistema_iconos} #{_config.sistema_iconos}-#{icono}"
116
+ end
119
117
  end
120
118
  end
@@ -0,0 +1,28 @@
1
+ module PgEngine
2
+ module FlashHelper
3
+ def render_turbo_stream_flash_messages
4
+ turbo_stream.prepend 'flash', partial: 'layouts/flash'
5
+ end
6
+
7
+ def render_turbo_stream_title
8
+ # rubocop:disable Rails/SkipsModelValidations
9
+ turbo_stream.update_all 'title', "#{breadcrumbs.last&.name} - #{Rails.application.class.module_parent_name}"
10
+ # rubocop:enable Rails/SkipsModelValidations
11
+ end
12
+
13
+ def flash_type_to_class(flash_type)
14
+ case flash_type
15
+ when 'notice'
16
+ 'info'
17
+ when 'error'
18
+ 'danger'
19
+ when 'alert'
20
+ 'warning'
21
+ when 'success'
22
+ 'success'
23
+ else
24
+ flash_type
25
+ end
26
+ end
27
+ end
28
+ end