pg_rails 7.1.16 → 7.2.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.
Files changed (27) hide show
  1. checksums.yaml +4 -4
  2. data/pg_engine/app/assets/stylesheets/pg_rails_b5.scss +7 -2
  3. data/pg_engine/app/components/bad_user_input_component.rb +16 -0
  4. data/pg_engine/app/components/date_selector_component.html.slim +14 -0
  5. data/pg_engine/app/components/date_selector_component.rb +19 -0
  6. data/pg_engine/app/controllers/pg_engine/base_controller.rb +5 -0
  7. data/pg_engine/app/controllers/users/date_jumper_controller.rb +50 -0
  8. data/pg_engine/app/controllers/users/notifications_controller.rb +1 -1
  9. data/pg_engine/app/inputs/pg_engine/fecha_input.rb +25 -1
  10. data/pg_engine/app/lib/pg_engine/date_jumper.rb +74 -0
  11. data/pg_engine/app/views/pg_engine/base/index.html.slim +1 -1
  12. data/pg_engine/config/routes.rb +1 -0
  13. data/pg_engine/config/simple_form/simple_form_bootstrap.rb +0 -16
  14. data/pg_engine/lib/pg_engine/configuracion.rb +11 -2
  15. data/pg_engine/lib/pg_engine/error.rb +3 -0
  16. data/pg_engine/lib/pg_engine.rb +1 -1
  17. data/pg_engine/spec/components/previews/alert_component_preview/list_group.html.slim +12 -0
  18. data/pg_engine/spec/components/previews/alert_component_preview.rb +2 -0
  19. data/pg_engine/spec/lib/pg_engine/date_jumper_spec.rb +55 -0
  20. data/pg_engine/spec/requests/users/date_jumper_spec.rb +148 -0
  21. data/pg_engine/spec/system/date_selector_spec.rb +35 -0
  22. data/pg_layout/app/javascript/controllers/date_selector_controller.js +60 -0
  23. data/pg_layout/app/javascript/controllers/index.js +6 -0
  24. data/pg_layout/app/javascript/controllers/popover_controller.js +10 -0
  25. data/pg_layout/app/javascript/controllers/popover_toggler_controller.js +29 -0
  26. data/pg_rails/lib/version.rb +1 -1
  27. metadata +54 -14
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fc6c2d6a41256b2a5b2093e50eb1aad097f039a60a0ee32ea4e7c4efd2f01133
4
- data.tar.gz: fcd00160147fc1dbfe25e3f632433fc34e83b69018af77fc2e22c20bd23c4b2a
3
+ metadata.gz: 7685689c316550976fd129e2d10357ce1a4e3242bc5a2468d69bcbfbefe58d6c
4
+ data.tar.gz: d23282693ed8d1dbbd0552b5212bf8c7a56f9846cfcd491bedc4f4753a4f7fbd
5
5
  SHA512:
6
- metadata.gz: c4c1efe2aff72b203b3e448dfa78eeb647b00da5ccb598c13b1679a8c7cbcee4db72a9c64b0196965109c77ba8b626dea1d95d98b66856218a16a74d94734f5d
7
- data.tar.gz: 2ec78e73c57f3c1665e55b8e8885624a2ae17af16588955ad8ab135296bbbf16f2208b2776b27696c523a8ba281c9445e98a7676fa420c46ec158240b717db52
6
+ metadata.gz: a4f384000a2f7955bf91658d863bb1d52c6997cf9eeb0e775b0b4fa236af21f6eee9e5730170ba24f15a64cd8f0a2883db1aac208b5e06413a619547d73de46f
7
+ data.tar.gz: 10f9768f3f69b517839b03da38197b27e4c37adbd6cd9490cddab952ed077884548c648b7d16a4f6f1713dd2e8f59b91b91c31b1f1364df813f5b60e9c5aea24
@@ -74,8 +74,8 @@ input[type=datetime-local], input[type=datetime] {
74
74
  }
75
75
 
76
76
  .list-group-item {
77
- --bs-list-group-item-padding-y: 0px;
78
- --bs-list-group-item-padding-x: 0.3rem;
77
+ --bs-list-group-item-padding-y: 0.3em;
78
+ --bs-list-group-item-padding-x: 1em;
79
79
  }
80
80
 
81
81
  // FILTROS
@@ -103,6 +103,11 @@ input[type=datetime-local], input[type=datetime] {
103
103
  width: min-content;
104
104
  }
105
105
 
106
+ // Popover
107
+ .modal-content, .popover {
108
+ box-shadow: 4px 4px 8px 0px rgba(0, 0, 0, 0.3);
109
+ }
110
+
106
111
  // Modal
107
112
  .modal-content {
108
113
  box-shadow: 15px 15px 9px 0px rgba(0, 0, 0, 0.6);
@@ -0,0 +1,16 @@
1
+ class BadUserInputComponent < BaseComponent
2
+ def initialize(error_msg:)
3
+ @error_msg = error_msg
4
+ super
5
+ end
6
+
7
+ def alert_type
8
+ :warning
9
+ end
10
+
11
+ erb_template <<~ERB
12
+ <div>
13
+ <%= @error_msg %>
14
+ </div>
15
+ ERB
16
+ end
@@ -0,0 +1,14 @@
1
+ .d-flex.flex-column.align-items-start.gap-2[
2
+ data-controller="date-selector" data-field-id="#{@field_id}"
3
+ ]
4
+ = number_field_tag 'quantity', nil,
5
+ placeholder: 'Cantidad', class: 'form-control form-control-sm'
6
+ = select_tag 'type', options_for_select(@types),
7
+ class: 'form-select form-select-sm'
8
+ = select_tag 'direction', options_for_select(@directions),
9
+ class: 'form-select form-select-sm'
10
+ .d-flex.justify-content-between.w-100
11
+ = button_tag 'Aceptar', class: 'btn btn-sm btn-primary',
12
+ 'data-action': 'date-selector#submit'
13
+ = button_tag 'Hoy', class: 'btn btn-sm btn-link float-end',
14
+ 'data-action': 'date-selector#today'
@@ -0,0 +1,19 @@
1
+ class DateSelectorComponent < ViewComponent::Base
2
+ def initialize(field_id)
3
+ @field_id = field_id
4
+
5
+ @types = [
6
+ ['Días corridos (L a D)', 'calendar_days'],
7
+ ['Días hábiles (L a V)', 'business_days'],
8
+ ['Días hábiles no feriados', 'business_days_excluding_holidays'],
9
+ ['Semanas', 'weeks'],
10
+ ['Meses', 'months']
11
+ ]
12
+
13
+ @directions = [
14
+ ['Hacia adelante', 'forward'],
15
+ ['Hacia atrás', 'backward']
16
+ ]
17
+ super
18
+ end
19
+ end
@@ -23,6 +23,7 @@ module PgEngine
23
23
  protect_from_forgery with: :exception
24
24
 
25
25
  rescue_from StandardError, with: :internal_error
26
+ rescue_from PgEngine::BadUserInput, with: :bad_user_input
26
27
  rescue_from ActionController::InvalidAuthenticityToken,
27
28
  with: :invalid_authenticity_token
28
29
 
@@ -32,6 +33,10 @@ module PgEngine
32
33
  redirect_to e.url
33
34
  end
34
35
 
36
+ def bad_user_input(error)
37
+ render_my_component(BadUserInputComponent.new(error_msg: error.message), :bad_request)
38
+ end
39
+
35
40
  def internal_error(error)
36
41
  pg_err error
37
42
 
@@ -0,0 +1,50 @@
1
+ module Users
2
+ class DateJumperController < PgEngine.config.users_controller
3
+ before_action only: :jump do
4
+ if params[:quantity].blank?
5
+ raise PgEngine::BadUserInput, 'Cantidad incorrecta'
6
+ end
7
+ end
8
+
9
+ def jump
10
+ start_date = Date.parse(params[:start_date])
11
+ quantity = params[:quantity].to_i
12
+
13
+ date =
14
+ case params[:type]
15
+ when 'calendar_days'
16
+ start_date + (multiplier * quantity.days)
17
+ when 'business_days', 'business_days_excluding_holidays'
18
+ resolve_business_days(start_date, quantity)
19
+ when 'weeks'
20
+ start_date + (multiplier * quantity.weeks)
21
+ when 'months'
22
+ start_date + (multiplier * quantity.months)
23
+ else
24
+ # :nocov:
25
+ raise PgEngine::Error, 'type no soportado'
26
+ # :nocov:
27
+ end
28
+
29
+ render json: { date: }
30
+ end
31
+
32
+ private
33
+
34
+ def resolve_business_days(start_date, quantity)
35
+ exclude_holidays = params[:type].include?('excluding_holidays')
36
+ options = { direction: params[:direction], exclude_holidays: }
37
+
38
+ PgEngine::DateJumper.new(start_date)
39
+ .business_days(quantity, **options)
40
+ end
41
+
42
+ def multiplier
43
+ if params[:direction] == 'forward'
44
+ 1
45
+ else
46
+ -1
47
+ end
48
+ end
49
+ end
50
+ end
@@ -1,5 +1,5 @@
1
1
  module Users
2
- class NotificationsController < ApplicationController
2
+ class NotificationsController < PgEngine.config.users_controller
3
3
  def mark_as_unseen
4
4
  notification = Noticed::Notification.find(params[:id])
5
5
  notification.mark_as_unseen!
@@ -10,11 +10,35 @@ module PgEngine
10
10
  else
11
11
  object.public_send(attribute_name)
12
12
  end
13
+
13
14
  @input_type = 'date'
14
15
 
15
16
  options = merge_wrapper_options({ value:, class: '', autocomplete: 'off' },
16
17
  wrapper_options)
17
- super(options)
18
+ if input_options[:date_selector]
19
+ content_tag 'div', class: 'd-flex align-items-center' do
20
+ super(options) + date_selector
21
+ end
22
+ else
23
+ super(options)
24
+ end
25
+ end
26
+
27
+ include ActionView::Helpers::FormTagHelper
28
+ def date_selector
29
+ field_id = @builder.field_id(attribute_name)
30
+ html = DateSelectorComponent.new(field_id).render_in(@builder.template)
31
+ # tabindex required: https://getbootstrap.com/docs/5.3/components/popovers/#dismiss-on-next-click
32
+ link_to 'javascript:void(0)',
33
+ class: 'btn btn-link', tabindex: 0,
34
+ data: {
35
+ controller: 'popover-toggler',
36
+ 'bs-html': true,
37
+ 'bs-title': 'Cambiar la fecha',
38
+ 'bs-content': html
39
+ } do
40
+ '<i class="bi bi-magic"></i>'.html_safe
41
+ end
18
42
  end
19
43
  end
20
44
  end
@@ -0,0 +1,74 @@
1
+ module PgEngine
2
+ class DateJumper
3
+ def initialize(start_date)
4
+ @start_date = start_date
5
+ end
6
+
7
+ def business_days(days, direction:, exclude_holidays: false)
8
+ case direction
9
+ when :forward, 'forward'
10
+ business_forward(days, exclude_holidays:)
11
+ when :backward, 'backward'
12
+ business_backward(days, exclude_holidays:)
13
+ else
14
+ # :nocov:
15
+ raise PgEngine::Error, 'direction not supported'
16
+ # :nocov:
17
+ end
18
+ end
19
+
20
+ def business_forward(days, exclude_holidays: false)
21
+ days.times.inject(@start_date) do |acc, _|
22
+ if exclude_holidays
23
+ find_excluding_holidays(method: :next_business_day, from: acc)
24
+ else
25
+ next_business_day(acc)
26
+ end
27
+ end
28
+ end
29
+
30
+ def business_backward(days, exclude_holidays: false)
31
+ days.times.inject(@start_date) do |acc, _|
32
+ if exclude_holidays
33
+ find_excluding_holidays(method: :prev_business_day, from: acc)
34
+ else
35
+ prev_business_day(acc)
36
+ end
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ def find_excluding_holidays(method:, from:)
43
+ aux = from
44
+ safe_counter = 0
45
+ loop do
46
+ safe_counter += 1
47
+ aux = send(method, aux)
48
+ if safe_counter > 10
49
+ # :nocov:
50
+ raise 'las cosas'
51
+ # :nocov:
52
+ end
53
+ break unless Holidays.on(aux, :ar).any?
54
+ end
55
+ aux
56
+ end
57
+
58
+ def next_business_day(date)
59
+ if date.wday.in? [0, 5, 6]
60
+ date.next_occurring(:monday)
61
+ else
62
+ date.advance(days: 1)
63
+ end
64
+ end
65
+
66
+ def prev_business_day(date)
67
+ if date.wday.in? [0, 1, 6]
68
+ date.prev_occurring(:friday)
69
+ else
70
+ date.advance(days: -1)
71
+ end
72
+ end
73
+ end
74
+ end
@@ -43,7 +43,7 @@ div
43
43
  - available_page_sizes.each do |page_size|
44
44
  = link_to page_size,
45
45
  namespaced_path(@clase_modelo, page_size:),
46
- class: "list-group-item #{'active' if current_page_size == page_size}"
46
+ class: "list-group-item py-0 px-1 #{'active' if current_page_size == page_size}"
47
47
  - elsif @records_filtered
48
48
  - i18n_key = "#{controller_key}.#{action_name}.index.empty_but_filtered"
49
49
  p.m-3
@@ -20,6 +20,7 @@ Rails.application.routes.draw do
20
20
  namespace :users, path: 'u' do
21
21
  post 'notifications/mark_as_seen', to: 'notifications#mark_as_seen'
22
22
  post 'notifications/mark_as_unseen', to: 'notifications#mark_as_unseen'
23
+ get 'date_jumper/jump'
23
24
  end
24
25
  namespace :admin, path: 'a' do
25
26
  pg_resource(:emails)
@@ -69,22 +69,6 @@ SimpleForm.setup do |config|
69
69
  b.use :hint, wrap_with: { class: 'form-text' }
70
70
  end
71
71
 
72
- config.wrappers :vertical_form_inline_wrap, class: 'mb-3' do |b|
73
- b.use :html5
74
- b.use :placeholder
75
- b.optional :maxlength
76
- b.optional :minlength
77
- b.optional :pattern
78
- b.optional :min_max
79
- b.optional :readonly
80
- b.use :label, class: 'form-label d-block'
81
- b.wrapper class: 'd-inline-block' do |bb|
82
- bb.use :input, class: 'form-control', error_class: 'is-invalid'
83
- end
84
- b.use :error, wrap_with: { class: 'invalid-feedback' }
85
- b.use :hint, wrap_with: { class: 'form-text' }
86
- end
87
-
88
72
  config.wrappers :vertical_no_margin_control, &control_wrapper
89
73
 
90
74
  config.wrappers :vertical_no_margin_select, &select_wrapper
@@ -4,8 +4,11 @@
4
4
 
5
5
  module PgEngine
6
6
  class Configuracion
7
- attr_accessor :sistema_iconos, :clase_botones_chicos, :boton_destroy, :boton_edit,
8
- :boton_show, :boton_light, :icono_destroy, :icono_edit, :icono_show, :boton_export, :bootstrap_version
7
+ attr_accessor :sistema_iconos, :clase_botones_chicos,
8
+ :boton_destroy, :boton_edit, :boton_show,
9
+ :boton_light, :icono_destroy, :icono_edit,
10
+ :icono_show, :boton_export, :bootstrap_version,
11
+ :users_controller
9
12
 
10
13
  def initialize
11
14
  @sistema_iconos = 'bi'
@@ -19,6 +22,12 @@ module PgEngine
19
22
  @icono_edit = 'pencil'
20
23
  @icono_show = 'eye-fill'
21
24
  @bootstrap_version = 5
25
+
26
+ if defined? UsersController
27
+ @users_controller = UsersController
28
+ elsif defined? FrontendController
29
+ @users_controller = FrontendController
30
+ end
22
31
  end
23
32
  end
24
33
  end
@@ -2,6 +2,9 @@ module PgEngine
2
2
  class Error < StandardError
3
3
  end
4
4
 
5
+ class BadUserInput < Error
6
+ end
7
+
5
8
  class PageNotFoundError < Error
6
9
  end
7
10
  end
@@ -53,6 +53,7 @@ require 'pg_search'
53
53
  require 'view_component'
54
54
  require 'noticed'
55
55
  require 'ransack_memory'
56
+ require 'holidays'
56
57
 
57
58
  if Rails.env.local?
58
59
  require 'letter_opener'
@@ -65,7 +66,6 @@ if Rails.env.local?
65
66
  require 'rubocop-rails'
66
67
  require 'rubocop-rspec'
67
68
  require 'slim_lint'
68
- require 'ruby-lint'
69
69
  require 'brakeman'
70
70
  require 'capybara'
71
71
  require 'selenium-webdriver'
@@ -0,0 +1,12 @@
1
+ h1 List groups
2
+
3
+ ul.list-group
4
+ li.list-group-item un ítem
5
+ li.list-group-item otro ítem
6
+
7
+ br
8
+ br
9
+
10
+ ul.list-group.list-group-horizontal
11
+ li.list-group-item un ítem
12
+ li.list-group-item otro ítem
@@ -9,4 +9,6 @@ class AlertComponentPreview < ViewComponent::Preview
9
9
  def colours; end
10
10
 
11
11
  def tooltips; end
12
+
13
+ def list_group; end
12
14
  end
@@ -0,0 +1,55 @@
1
+ require 'rails_helper'
2
+
3
+ describe PgEngine::DateJumper do
4
+ subject do
5
+ jumper.send(method, days, exclude_holidays:)
6
+ end
7
+
8
+ let(:method) { self.class.metadata[:method] }
9
+ let(:jumper) { described_class.new(start_date) }
10
+ let(:start_date) { Date.new(2024, 8, 16) }
11
+ let(:days) { 5 }
12
+ let(:exclude_holidays) { false }
13
+
14
+ def fake_holiday(date)
15
+ allow(Holidays).to receive(:on).and_call_original
16
+ allow(Holidays).to receive(:on).with(date, anything)
17
+ .and_return([:some_fake_holiday])
18
+ end
19
+
20
+ describe 'business_forward', method: 'business_forward' do
21
+ it do
22
+ expect(subject).to eq Date.new(2024, 8, 23)
23
+ end
24
+
25
+ context 'excluding holidays' do
26
+ before do
27
+ fake_holiday(Date.new(2024, 8, 23))
28
+ end
29
+
30
+ let(:exclude_holidays) { true }
31
+
32
+ it do
33
+ expect(subject).to eq Date.new(2024, 8, 26)
34
+ end
35
+ end
36
+ end
37
+
38
+ describe 'business_forward', method: 'business_backward' do
39
+ it do
40
+ expect(subject).to eq Date.new(2024, 8, 9)
41
+ end
42
+
43
+ context 'excluding holidays' do
44
+ before do
45
+ fake_holiday(Date.new(2024, 8, 14))
46
+ end
47
+
48
+ let(:exclude_holidays) { true }
49
+
50
+ it do
51
+ expect(subject).to eq Date.new(2024, 8, 8)
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,148 @@
1
+ require 'rails_helper'
2
+
3
+ RSpec.describe 'Users::DateJumpers' do
4
+ before do
5
+ user = create :user
6
+ sign_in user
7
+ end
8
+
9
+ describe 'GET /jump' do
10
+ before do
11
+ stubs if defined? stubs
12
+ get '/u/date_jumper/jump', params: {
13
+ start_date:,
14
+ quantity:,
15
+ type:,
16
+ direction:
17
+ }, headers: { accept: 'application/json' }
18
+ end
19
+
20
+ let(:start_date) { Date.new(2024, 8, 16) }
21
+ let(:quantity) { 5 }
22
+
23
+ context 'when quantity is blank' do
24
+ let(:quantity) { '' }
25
+ let(:type) { 'calendar_days' }
26
+ let(:direction) { 'forward' }
27
+
28
+ it do
29
+ expect(response).to have_http_status(:bad_request)
30
+ expect(JSON.parse(response.body)['html']).to include 'Cantidad incorrecta'
31
+ end
32
+ end
33
+
34
+ context 'when moving calendar days' do
35
+ let(:type) { 'calendar_days' }
36
+
37
+ context 'forward' do
38
+ let(:direction) { 'forward' }
39
+
40
+ it do
41
+ expect(JSON.parse(response.body)['date']).to eq '2024-08-21'
42
+ end
43
+ end
44
+
45
+ context 'backward' do
46
+ let(:direction) { 'backward' }
47
+
48
+ it do
49
+ expect(JSON.parse(response.body)['date']).to eq '2024-08-11'
50
+ end
51
+ end
52
+ end
53
+
54
+ context 'when moving business days' do
55
+ let(:type) { 'business_days' }
56
+
57
+ context 'forward' do
58
+ let(:direction) { 'forward' }
59
+
60
+ it do
61
+ expect(JSON.parse(response.body)['date']).to eq '2024-08-23'
62
+ end
63
+ end
64
+
65
+ context 'backward' do
66
+ let(:direction) { 'backward' }
67
+
68
+ it do
69
+ expect(JSON.parse(response.body)['date']).to eq '2024-08-09'
70
+ end
71
+ end
72
+ end
73
+
74
+ context 'when moving business days excluding holidays' do
75
+ def fake_holiday(date)
76
+ allow(Holidays).to receive(:on).and_call_original
77
+ allow(Holidays).to receive(:on).with(date, anything)
78
+ .and_return([:some_fake_holiday])
79
+ end
80
+
81
+ let(:type) { 'business_days_excluding_holidays' }
82
+
83
+ context 'forward' do
84
+ let(:stubs) do
85
+ fake_holiday(Date.new(2024, 8, 23))
86
+ end
87
+
88
+ let(:direction) { 'forward' }
89
+
90
+ it do
91
+ expect(JSON.parse(response.body)['date']).to eq '2024-08-26'
92
+ end
93
+ end
94
+
95
+ context 'backward' do
96
+ let(:stubs) do
97
+ fake_holiday(Date.new(2024, 8, 14))
98
+ end
99
+
100
+ let(:direction) { 'backward' }
101
+
102
+ it do
103
+ expect(JSON.parse(response.body)['date']).to eq '2024-08-08'
104
+ end
105
+ end
106
+ end
107
+
108
+ context 'when moving weeks' do
109
+ let(:type) { 'weeks' }
110
+
111
+ context 'forward' do
112
+ let(:direction) { 'forward' }
113
+
114
+ it do
115
+ expect(JSON.parse(response.body)['date']).to eq '2024-09-20'
116
+ end
117
+ end
118
+
119
+ context 'backward' do
120
+ let(:direction) { 'backward' }
121
+
122
+ it do
123
+ expect(JSON.parse(response.body)['date']).to eq '2024-07-12'
124
+ end
125
+ end
126
+ end
127
+
128
+ context 'when moving months' do
129
+ let(:type) { 'months' }
130
+
131
+ context 'forward' do
132
+ let(:direction) { 'forward' }
133
+
134
+ it do
135
+ expect(JSON.parse(response.body)['date']).to eq '2025-01-16'
136
+ end
137
+ end
138
+
139
+ context 'backward' do
140
+ let(:direction) { 'backward' }
141
+
142
+ it do
143
+ expect(JSON.parse(response.body)['date']).to eq '2024-03-16'
144
+ end
145
+ end
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,35 @@
1
+ # Initially generated with PgRails::SystemSpecGenerator
2
+ # https://github.com/martin-rosso/pg_rails
3
+
4
+ require 'rails_helper'
5
+
6
+ # By default uses selenium_chrome_headless_iphone driver
7
+ # run with DRIVER environment variable to override, eg:
8
+ #
9
+ # DRIVER=selenium rspec
10
+ describe 'Date selector' do
11
+ subject(:visitar) do
12
+ visit edit_admin_categoria_de_cosa_path(categoria_de_cosa)
13
+ end
14
+
15
+ let(:logged_user) { create :user }
16
+ let(:account) { logged_user.current_account }
17
+ let(:categoria_de_cosa) { create :categoria_de_cosa, fecha: }
18
+ let(:fecha) { Date.new(2024, 8, 12) }
19
+
20
+ before do
21
+ login_as logged_user
22
+ end
23
+
24
+ describe 'jump N days' do
25
+ it do
26
+ visitar
27
+ find('.categoria_de_cosa_fecha [data-controller="popover-toggler"]').click
28
+ fill_in 'quantity', with: '3'
29
+ select 'Días hábiles (L a V)'
30
+ click_on 'Aceptar'
31
+ click_on 'Actualizar Categoría de cosa'
32
+ expect(page).to have_text '15/08/2024'
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,60 @@
1
+ import { Controller } from '@hotwired/stimulus'
2
+ import { flashMessage } from '../utils/utils'
3
+ import { get } from '@rails/request.js'
4
+ import Rollbar from 'rollbar'
5
+
6
+ export default class extends Controller {
7
+ today () {
8
+ const fechaEl = document.getElementById(this.element.dataset.fieldId)
9
+ let today = new Date()
10
+ const dd = String(today.getDate()).padStart(2, '0')
11
+ const mm = String(today.getMonth() + 1).padStart(2, '0') // January is 0!
12
+ const yyyy = today.getFullYear()
13
+
14
+ today = yyyy + '-' + mm + '-' + dd
15
+ fechaEl.value = today
16
+ }
17
+
18
+ closePopover () {
19
+ const popover = this.element.closest('.popover')
20
+ this.application.getControllerForElementAndIdentifier(popover, 'popover').close()
21
+ }
22
+
23
+ async submit () {
24
+ const quantity = this.element.querySelector('input[name=quantity]').value
25
+ if (!quantity) {
26
+ this.closePopover()
27
+ return
28
+ }
29
+ const type = this.element.querySelector('select[name=type]').value
30
+ const direction = this.element.querySelector('select[name=direction]').value
31
+ const fechaEl = document.getElementById(this.element.dataset.fieldId)
32
+ const startDate = fechaEl.value
33
+ // console.log(quantity, type, direction)
34
+ this.element.querySelector('button').setAttribute('disabled', 'true')
35
+ // let input = this
36
+ const response = await get('/u/date_jumper/jump', {
37
+ query: {
38
+ start_date: startDate,
39
+ quantity,
40
+ type,
41
+ direction
42
+ },
43
+ responseKind: 'json'
44
+ })
45
+
46
+ if (response.ok) {
47
+ const json = await response.json
48
+ fechaEl.value = json.date
49
+ this.element.querySelector('button').removeAttribute('disabled')
50
+ this.closePopover()
51
+ } else {
52
+ const json = await response.json
53
+ // FIXME: handle JSON parse error
54
+ const message = json.html || 'Hubo un error'
55
+ flashMessage(message, 'warning', true)
56
+ this.element.querySelector('button').removeAttribute('disabled')
57
+ Rollbar.error('date jumper error', json)
58
+ }
59
+ }
60
+ }
@@ -11,6 +11,9 @@ import NotificationsController from './notifications_controller'
11
11
  import SelectizeController from './selectize_controller'
12
12
  import ThemeController from './theme_controller'
13
13
  import TooltipController from './tooltip_controller'
14
+ import PopoverController from './popover_controller'
15
+ import PopoverTogglerController from './popover_toggler_controller'
16
+ import DateSelectorController from './date_selector_controller'
14
17
 
15
18
  application.register('navbar', NavbarController)
16
19
  application.register('nested', NestedController)
@@ -23,5 +26,8 @@ application.register('notifications', NotificationsController)
23
26
  application.register('selectize', SelectizeController)
24
27
  application.register('theme', ThemeController)
25
28
  application.register('tooltip', TooltipController)
29
+ application.register('popover', PopoverController)
30
+ application.register('popover-toggler', PopoverTogglerController)
31
+ application.register('date-selector', DateSelectorController)
26
32
 
27
33
  // TODO: testear con capybara todo lo que se pueda
@@ -0,0 +1,10 @@
1
+ import { Controller } from '@hotwired/stimulus'
2
+ import * as bootstrap from 'bootstrap'
3
+
4
+ export default class extends Controller {
5
+ close () {
6
+ const toggler = document.querySelector('[aria-describedby="' + this.element.id + '"]')
7
+ const instance = bootstrap.Popover.getInstance(toggler)
8
+ instance.hide()
9
+ }
10
+ }
@@ -0,0 +1,29 @@
1
+ import { Controller } from '@hotwired/stimulus'
2
+ import * as bootstrap from 'bootstrap'
3
+
4
+ export default class extends Controller {
5
+ popover = null
6
+
7
+ connect () {
8
+ this.popover = new bootstrap.Popover(this.element, {
9
+ // WARNING: don't use for user input html
10
+ sanitize: false,
11
+ template: `
12
+ <div class="popover" role="tooltip" data-controller="popover">
13
+ <div class="popover-arrow"></div>
14
+ <div class="popover-header"></div>
15
+ <button type="button" class="btn-close position-absolute" data-action="popover#close" style="top: 1em; right: 1em;" aria-label="Close"></button>
16
+ <div class="popover-body">
17
+ </div>
18
+ </div>
19
+ `,
20
+ container: 'body'
21
+ })
22
+ }
23
+
24
+ disconnect () {
25
+ if (this.popover) {
26
+ this.popover.dispose()
27
+ }
28
+ }
29
+ }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PgRails
4
- VERSION = '7.1.16'
4
+ VERSION = '7.2.1'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pg_rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.1.16
4
+ version: 7.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Martín Rosso
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-08-14 00:00:00.000000000 Z
11
+ date: 2024-08-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 7.1.3.4
19
+ version: 7.2.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 7.1.3.4
26
+ version: 7.2.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: anycable
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - '='
32
32
  - !ruby/object:Gem::Version
33
- version: 1.5.0
33
+ version: 1.5.1
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - '='
39
39
  - !ruby/object:Gem::Version
40
- version: 1.5.0
40
+ version: 1.5.1
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: anycable-rails
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -212,14 +212,14 @@ dependencies:
212
212
  requirements:
213
213
  - - "~>"
214
214
  - !ruby/object:Gem::Version
215
- version: 2.7.0
215
+ version: 2.8.1
216
216
  type: :runtime
217
217
  prerelease: false
218
218
  version_requirements: !ruby/object:Gem::Requirement
219
219
  requirements:
220
220
  - - "~>"
221
221
  - !ruby/object:Gem::Version
222
- version: 2.7.0
222
+ version: 2.8.1
223
223
  - !ruby/object:Gem::Dependency
224
224
  name: nokogiri
225
225
  requirement: !ruby/object:Gem::Requirement
@@ -296,14 +296,14 @@ dependencies:
296
296
  requirements:
297
297
  - - "~>"
298
298
  - !ruby/object:Gem::Version
299
- version: 5.4.3
299
+ version: 5.7.0
300
300
  type: :runtime
301
301
  prerelease: false
302
302
  version_requirements: !ruby/object:Gem::Requirement
303
303
  requirements:
304
304
  - - "~>"
305
305
  - !ruby/object:Gem::Version
306
- version: 5.4.3
306
+ version: 5.7.0
307
307
  - !ruby/object:Gem::Dependency
308
308
  name: pundit
309
309
  requirement: !ruby/object:Gem::Requirement
@@ -366,14 +366,14 @@ dependencies:
366
366
  requirements:
367
367
  - - "~>"
368
368
  - !ruby/object:Gem::Version
369
- version: 3.4.2
369
+ version: '3.5'
370
370
  type: :runtime
371
371
  prerelease: false
372
372
  version_requirements: !ruby/object:Gem::Requirement
373
373
  requirements:
374
374
  - - "~>"
375
375
  - !ruby/object:Gem::Version
376
- version: 3.4.2
376
+ version: '3.5'
377
377
  - !ruby/object:Gem::Dependency
378
378
  name: jsbundling-rails
379
379
  requirement: !ruby/object:Gem::Requirement
@@ -528,6 +528,20 @@ dependencies:
528
528
  - - "~>"
529
529
  - !ruby/object:Gem::Version
530
530
  version: 2.3.6
531
+ - !ruby/object:Gem::Dependency
532
+ name: ransack
533
+ requirement: !ruby/object:Gem::Requirement
534
+ requirements:
535
+ - - "~>"
536
+ - !ruby/object:Gem::Version
537
+ version: 4.2.1
538
+ type: :runtime
539
+ prerelease: false
540
+ version_requirements: !ruby/object:Gem::Requirement
541
+ requirements:
542
+ - - "~>"
543
+ - !ruby/object:Gem::Version
544
+ version: 4.2.1
531
545
  - !ruby/object:Gem::Dependency
532
546
  name: ransack_memory
533
547
  requirement: !ruby/object:Gem::Requirement
@@ -548,14 +562,14 @@ dependencies:
548
562
  requirements:
549
563
  - - "~>"
550
564
  - !ruby/object:Gem::Version
551
- version: 3.12.1
565
+ version: '3.13'
552
566
  type: :runtime
553
567
  prerelease: false
554
568
  version_requirements: !ruby/object:Gem::Requirement
555
569
  requirements:
556
570
  - - "~>"
557
571
  - !ruby/object:Gem::Version
558
- version: 3.12.1
572
+ version: '3.13'
559
573
  - !ruby/object:Gem::Dependency
560
574
  name: noticed
561
575
  requirement: !ruby/object:Gem::Requirement
@@ -570,6 +584,20 @@ dependencies:
570
584
  - - "~>"
571
585
  - !ruby/object:Gem::Version
572
586
  version: '2.3'
587
+ - !ruby/object:Gem::Dependency
588
+ name: holidays
589
+ requirement: !ruby/object:Gem::Requirement
590
+ requirements:
591
+ - - "~>"
592
+ - !ruby/object:Gem::Version
593
+ version: '8.8'
594
+ type: :runtime
595
+ prerelease: false
596
+ version_requirements: !ruby/object:Gem::Requirement
597
+ requirements:
598
+ - - "~>"
599
+ - !ruby/object:Gem::Version
600
+ version: '8.8'
573
601
  description: Rails goodies.
574
602
  email:
575
603
  - mrosso10@gmail.com
@@ -611,7 +639,10 @@ files:
611
639
  - pg_engine/app/components/alert_component.html.slim
612
640
  - pg_engine/app/components/alert_component.rb
613
641
  - pg_engine/app/components/bad_request_component.rb
642
+ - pg_engine/app/components/bad_user_input_component.rb
614
643
  - pg_engine/app/components/base_component.rb
644
+ - pg_engine/app/components/date_selector_component.html.slim
645
+ - pg_engine/app/components/date_selector_component.rb
615
646
  - pg_engine/app/components/flash_container_component.rb
616
647
  - pg_engine/app/components/internal_error_component.rb
617
648
  - pg_engine/app/components/notification_component.rb
@@ -635,6 +666,7 @@ files:
635
666
  - pg_engine/app/controllers/public/mensaje_contactos_controller.rb
636
667
  - pg_engine/app/controllers/public/webhooks_controller.rb
637
668
  - pg_engine/app/controllers/users/confirmations_controller.rb
669
+ - pg_engine/app/controllers/users/date_jumper_controller.rb
638
670
  - pg_engine/app/controllers/users/notifications_controller.rb
639
671
  - pg_engine/app/controllers/users/registrations_controller.rb
640
672
  - pg_engine/app/decorators/account_decorator.rb
@@ -654,6 +686,7 @@ files:
654
686
  - pg_engine/app/helpers/pg_engine/print_helper.rb
655
687
  - pg_engine/app/helpers/pg_engine/route_helper.rb
656
688
  - pg_engine/app/inputs/pg_engine/fecha_input.rb
689
+ - pg_engine/app/lib/pg_engine/date_jumper.rb
657
690
  - pg_engine/app/lib/pg_engine/devise_failure_app.rb
658
691
  - pg_engine/app/lib/pg_engine/error_helper.rb
659
692
  - pg_engine/app/lib/pg_engine/filtros_builder.rb
@@ -767,6 +800,7 @@ files:
767
800
  - pg_engine/spec/components/previews/alert_component_preview/colours.html.slim
768
801
  - pg_engine/spec/components/previews/alert_component_preview/default.html.slim
769
802
  - pg_engine/spec/components/previews/alert_component_preview/dismisible.html.slim
803
+ - pg_engine/spec/components/previews/alert_component_preview/list_group.html.slim
770
804
  - pg_engine/spec/components/previews/alert_component_preview/tooltips.html.slim
771
805
  - pg_engine/spec/components/previews/internal_error_preview.rb
772
806
  - pg_engine/spec/components/previews/internal_error_preview/default.html.slim
@@ -792,6 +826,7 @@ files:
792
826
  - pg_engine/spec/fixtures/test.pdf
793
827
  - pg_engine/spec/helpers/pg_engine/pg_rails_helper_spec.rb
794
828
  - pg_engine/spec/helpers/pg_engine/print_helper_spec.rb
829
+ - pg_engine/spec/lib/pg_engine/date_jumper_spec.rb
795
830
  - pg_engine/spec/lib/pg_engine/error_helper_spec.rb
796
831
  - pg_engine/spec/lib/pg_engine/mailgun/log_sync_spec.rb
797
832
  - pg_engine/spec/lib/pg_engine/utils/pg_engine/pg_logger_spec.rb
@@ -807,7 +842,9 @@ files:
807
842
  - pg_engine/spec/pg_engine/pdf_preview_generator_spec.rb
808
843
  - pg_engine/spec/requests/admin/eventos_spec.rb
809
844
  - pg_engine/spec/requests/base_controller_requests_spec.rb
845
+ - pg_engine/spec/requests/users/date_jumper_spec.rb
810
846
  - pg_engine/spec/system/alerts_spec.rb
847
+ - pg_engine/spec/system/date_selector_spec.rb
811
848
  - pg_engine/spec/system/destroy_spec.rb
812
849
  - pg_engine/spec/system/login_spec.rb
813
850
  - pg_engine/spec/system/noticed_spec.rb
@@ -830,6 +867,7 @@ files:
830
867
  - pg_layout/app/javascript/config/turbo_rails/set_consumer.js
831
868
  - pg_layout/app/javascript/controllers/application.js
832
869
  - pg_layout/app/javascript/controllers/clear_timeout_controller.js
870
+ - pg_layout/app/javascript/controllers/date_selector_controller.js
833
871
  - pg_layout/app/javascript/controllers/fadein_onload_controller.js
834
872
  - pg_layout/app/javascript/controllers/filtros_controller.js
835
873
  - pg_layout/app/javascript/controllers/index.js
@@ -837,6 +875,8 @@ files:
837
875
  - pg_layout/app/javascript/controllers/nested_controller.js
838
876
  - pg_layout/app/javascript/controllers/notifications_controller.js
839
877
  - pg_layout/app/javascript/controllers/pg_form_controller.js
878
+ - pg_layout/app/javascript/controllers/popover_controller.js
879
+ - pg_layout/app/javascript/controllers/popover_toggler_controller.js
840
880
  - pg_layout/app/javascript/controllers/selectize_controller.js
841
881
  - pg_layout/app/javascript/controllers/switcher_controller.js
842
882
  - pg_layout/app/javascript/controllers/theme_controller.js