avo 2.43.0 → 2.45.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of avo might be problematic. Click here for more details.

Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -0
  3. data/Gemfile.lock +5 -1
  4. data/app/components/avo/index/resource_table_component.html.erb +2 -2
  5. data/app/components/avo/index/resource_table_component.rb +16 -0
  6. data/app/components/avo/paginator_component.html.erb +29 -40
  7. data/app/components/avo/paginator_component.rb +18 -0
  8. data/app/components/avo/views/resource_edit_component.html.erb +6 -4
  9. data/app/controllers/avo/actions_controller.rb +8 -10
  10. data/app/controllers/avo/application_controller.rb +0 -1
  11. data/app/controllers/avo/associations_controller.rb +1 -1
  12. data/app/controllers/avo/base_controller.rb +8 -9
  13. data/app/javascript/js/application.js +3 -0
  14. data/app/javascript/js/controllers/action_controller.js +2 -2
  15. data/app/views/avo/actions/show.html.erb +1 -2
  16. data/app/views/avo/partials/_flash_alerts.turbo_stream.erb +1 -1
  17. data/avo.gemspec +1 -0
  18. data/config/i18n-tasks.yml +1 -1
  19. data/config/initializers/pagy.rb +2 -0
  20. data/lib/avo/base_action.rb +17 -31
  21. data/lib/avo/base_resource.rb +1 -0
  22. data/lib/avo/concerns/pagination.rb +53 -0
  23. data/lib/avo/fields/base_field.rb +13 -7
  24. data/lib/avo/version.rb +1 -1
  25. data/lib/generators/avo/templates/locales/avo.ar.yml +5 -5
  26. data/lib/generators/avo/templates/locales/avo.en.yml +2 -0
  27. data/lib/generators/avo/templates/locales/avo.es.yml +126 -0
  28. data/lib/generators/avo/templates/locales/avo.fr.yml +2 -0
  29. data/lib/generators/avo/templates/locales/avo.nb.yml +2 -0
  30. data/lib/generators/avo/templates/locales/avo.nn.yml +2 -0
  31. data/lib/generators/avo/templates/locales/avo.pt-BR.yml +2 -0
  32. data/lib/generators/avo/templates/locales/avo.pt.yml +2 -0
  33. data/lib/generators/avo/templates/locales/avo.ro.yml +2 -0
  34. data/lib/generators/avo/templates/locales/avo.tr.yml +2 -0
  35. data/public/avo-assets/avo.base.js +176 -176
  36. data/public/avo-assets/avo.base.js.map +3 -3
  37. metadata +18 -4
  38. data/app/controllers/avo/team_users_controller.rb +0 -4
  39. data/lib/avo/action_model.rb +0 -20
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e46a221f03c28ba77e3a9ab32d841176eb9ecf7125161742ad0e1c222063d1b0
4
- data.tar.gz: 53a6aced2acfe8347472915e2d1c757ab7125b4189c333b1a849b23e51e306f5
3
+ metadata.gz: 3eeaf7c4479bd7cd5c0e45ca017ab8527a0d0ddf5fe625bc0bee728d5be654eb
4
+ data.tar.gz: 6f8538be2082861d11a2c150cd670733978d8631885aa7693c0d6b9770a97535
5
5
  SHA512:
6
- metadata.gz: 6c911463f13e7556ac9a9340ab45d67e18ee9130a542d5d12db3d728dbf62e4abe74f09ffc6cf9bfb4fa5b578396461715ba47ffc2a006680a6460ec25e748bd
7
- data.tar.gz: 7399602dd68b5442f19ed38a483373c95cde447a43fba2108e6e3e76905888f547841fd81675700c7467d0f035aab5a5563cc2a870ced29faf74581818266396
6
+ metadata.gz: 48a019b6179859de05f19839922ae41f391f08112f436c0946a526c5b36bc027855f5220c118c0588c66fecaea0d5ba59978d98803b1311884261f472f267efc
7
+ data.tar.gz: a5e00b21b9c62e5825718aec9bff93d8759b67f318edd93ba488a3f2caa2d7af3d7143f25917b6d475557b5d52648dc8f23bdb09d95194bc8278531be653e722
data/Gemfile CHANGED
@@ -167,3 +167,5 @@ gem "image_processing", "~> 1.12"
167
167
  gem "prefixed_ids"
168
168
 
169
169
  gem "mapkick-rb", "~> 0.1.4"
170
+
171
+ gem "turbo_power", "~> 0.5.0"
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- avo (2.43.0)
4
+ avo (2.45.0)
5
5
  actionview (>= 6.0)
6
6
  active_link_to
7
7
  activerecord (>= 6.0)
@@ -13,6 +13,7 @@ PATH
13
13
  meta-tags
14
14
  pagy
15
15
  turbo-rails
16
+ turbo_power (~> 0.5.0)
16
17
  view_component (>= 2.54.0)
17
18
  zeitwerk (>= 2.6.2)
18
19
 
@@ -419,6 +420,8 @@ GEM
419
420
  actionpack (>= 6.0.0)
420
421
  activejob (>= 6.0.0)
421
422
  railties (>= 6.0.0)
423
+ turbo_power (0.5.0)
424
+ turbo-rails (~> 1.3)
422
425
  tzinfo (2.0.6)
423
426
  concurrent-ruby (~> 1.0)
424
427
  unicode-display_width (2.4.0)
@@ -518,6 +521,7 @@ DEPENDENCIES
518
521
  sprockets-rails
519
522
  standard
520
523
  test-prof
524
+ turbo_power (~> 0.5.0)
521
525
  tzinfo-data
522
526
  web-console (>= 3.3.0)
523
527
  webdrivers (>= 5.3.0)
@@ -11,7 +11,7 @@
11
11
  <div class="absolute z-30 w-full ml-10 pt-px hidden" data-item-select-all-target="selectAllOverlay">
12
12
  <div class="bg-white flex items-center h-9 mt-0.5">
13
13
  <div class="mt-1.5" data-item-select-all-target="unselectedMessage">
14
- <%= t "avo.x_records_selected_from_a_total_of_x_html", selected: pagy.in, count: pagy.count %>
14
+ <%= selected_page_label %>
15
15
  <%= a_link request.url,
16
16
  size: :xs,
17
17
  color: :primary,
@@ -22,7 +22,7 @@
22
22
  <% end %>
23
23
  </div>
24
24
  <div class="mt-1.5" data-item-select-all-target="selectedMessage" class="hidden">
25
- <%= t "avo.x_records_selected_from_all_pages_html", count: pagy.count %>
25
+ <%= selected_all_label %>
26
26
  <%= a_link request.url,
27
27
  size: :xs,
28
28
  color: :primary,
@@ -22,4 +22,20 @@ class Avo::Index::ResourceTableComponent < ViewComponent::Base
22
22
  purpose: :select_all
23
23
  )
24
24
  end
25
+
26
+ def selected_page_label
27
+ if @resource.pagination_type.countless?
28
+ t "avo.x_records_selected_from_page_html", selected: pagy.in
29
+ else
30
+ t "avo.x_records_selected_from_a_total_of_x_html", selected: pagy.in, count: pagy.count
31
+ end
32
+ end
33
+
34
+ def selected_all_label
35
+ if @resource.pagination_type.countless?
36
+ t "avo.records_selected_from_all_pages_html"
37
+ else
38
+ t "avo.x_records_selected_from_all_pages_html", count: pagy.count
39
+ end
40
+ end
25
41
  end
@@ -1,47 +1,36 @@
1
- <%
2
- per_page_options = [*Avo.configuration.per_page_steps, Avo.configuration.per_page.to_i, index_params[:per_page].to_i]
3
-
4
- if parent_model.present?
5
- per_page_options.prepend Avo.configuration.via_per_page
6
- end
7
-
8
- per_page_options = per_page_options.sort.uniq
9
- %>
10
- <% unless @pagy.pages <= 1 && discreet_pagination %>
11
- <div class="flex flex-col sm:flex-row items-center justify-between aborder-t aborder-slate-200 rounded-xl space-y-2 sm:space-y-0">
12
- <div class="flex-2 sm:flex sm:items-center sm:justify-between">
13
- <div>
14
- <div class="text-sm leading-5 text-slate-600 flex items-center">
15
- <div data-controller="per-page">
16
- <div class="flex items-center">
17
- <%= select_tag 'per_page',
18
- options_for_select(per_page_options, index_params[:per_page]),
19
- class: 'appearance-none inline-flex bg-white-100 disabled:bg-white-400 disabled:cursor-not-allowed focus:bg-white text-slate-700 disabled:text-slate-600 rounded-md py-1 px-2 leading-tight border border-slate-300 outline-none focus:border-slate-400 outline w-16 mr-1 text-sm',
20
- data: {
21
- 'turbo-frame': turbo_frame,
22
- 'per-page-target': 'selector',
23
- action: 'change->per-page#reload'
24
- }
25
- %> <%= t('avo.per_page').downcase %>
26
- </div>
27
- <% per_page_options.each do |option| %>
28
- <%= link_to "Change to #{option} items per page", change_items_per_page_url(option), class: 'hidden', 'data-per-page-option': option, 'data-turbo-frame': turbo_frame %>
29
- <% end %>
1
+ <div class="flex flex-col sm:flex-row items-center justify-between aborder-t aborder-slate-200 rounded-xl space-y-2 sm:space-y-0">
2
+ <div class="flex-2 sm:flex sm:items-center sm:justify-between">
3
+ <div>
4
+ <div class="text-sm leading-5 text-slate-600 flex items-center">
5
+ <div data-controller="per-page">
6
+ <div class="flex items-center">
7
+ <%= select_tag 'per_page',
8
+ options_for_select(per_page_options, index_params[:per_page]),
9
+ class: 'appearance-none inline-flex bg-white-100 disabled:bg-white-400 disabled:cursor-not-allowed focus:bg-white text-slate-700 disabled:text-slate-600 rounded-md py-1 px-2 leading-tight border border-slate-300 outline-none focus:border-slate-400 outline w-16 mr-1 text-sm',
10
+ data: {
11
+ 'turbo-frame': turbo_frame,
12
+ 'per-page-target': 'selector',
13
+ action: 'change->per-page#reload'
14
+ }
15
+ %> <%= t('avo.per_page').downcase %>
30
16
  </div>
17
+ <% per_page_options.each do |option| %>
18
+ <%= link_to "Change to #{option} items per page", change_items_per_page_url(option), class: 'hidden', 'data-per-page-option': option, 'data-turbo-frame': turbo_frame %>
19
+ <% end %>
31
20
  </div>
32
21
  </div>
33
22
  </div>
34
- <div class="flex">
35
- <div class="flex-2 sm:flex sm:items-center sm:justify-between space-y-2 sm:space-y-0 text-center sm:text-left">
36
- <% if @pagy.count > 0 %>
37
- <div class="text-sm text-slate-600 mr-4"><%== helpers.pagy_info @pagy %></div>
38
- <% end %>
23
+ </div>
24
+ <div class="flex">
25
+ <div class="flex-2 sm:flex sm:items-center sm:justify-between space-y-2 sm:space-y-0 text-center sm:text-left">
26
+ <% if @resource.pagination_type.default? %>
27
+ <div class="text-sm text-slate-600 mr-4"><%== helpers.pagy_info @pagy %></div>
28
+ <% end %>
39
29
 
40
- <% if @pagy.pages > 1 %>
41
- <%# @todo: add first & last page. make the first and last buttons rounded %>
42
- <%== helpers.pagy_nav @pagy %>
43
- <% end %>
44
- </div>
30
+ <% if pagy.pages > 1 %>
31
+ <%# @todo: add first & last page. make the first and last buttons rounded %>
32
+ <%== helpers.pagy_nav @pagy %>
33
+ <% end %>
45
34
  </div>
46
35
  </div>
47
- <% end %>
36
+ </div>
@@ -24,4 +24,22 @@ class Avo::PaginatorComponent < ViewComponent::Base
24
24
  helpers.resources_path(resource: resource, per_page: option, keep_query_params: true, page: 1)
25
25
  end
26
26
  end
27
+
28
+ def render?
29
+ return false if discreet_pagination && pagy.pages <= 1
30
+
31
+ @pagy.items > 0
32
+ end
33
+
34
+ def per_page_options
35
+ @per_page_options ||= begin
36
+ options = [*Avo.configuration.per_page_steps, Avo.configuration.per_page.to_i, index_params[:per_page].to_i]
37
+
38
+ if parent_model.present?
39
+ options.prepend Avo.configuration.via_per_page
40
+ end
41
+
42
+ options.sort.uniq
43
+ end
44
+ end
27
45
  end
@@ -81,10 +81,12 @@
81
81
  <% if Avo.configuration.buttons_on_form_footers %>
82
82
  <% c.with_footer_tools do %>
83
83
  <div class="mt-4">
84
- <%= a_link back_path,
85
- style: :text,
86
- icon: 'arrow-left' do %>
87
- <%= t('avo.cancel').capitalize %>
84
+ <% if back_path.present? %>
85
+ <%= a_link back_path,
86
+ style: :text,
87
+ icon: 'arrow-left' do %>
88
+ <%= t('avo.cancel').capitalize %>
89
+ <% end %>
88
90
  <% end %>
89
91
  <% if can_see_the_save_button? %>
90
92
  <%= a_button color: :primary,
@@ -16,7 +16,6 @@ module Avo
16
16
  @view = :new
17
17
 
18
18
  @resource.hydrate(model: @model, view: @view, user: _current_user, params: params)
19
- @model = ActionModel.new @action.get_attributes_for_action
20
19
  end
21
20
 
22
21
  def handle
@@ -79,19 +78,18 @@ module Avo
79
78
  end
80
79
 
81
80
  respond_to do |format|
82
- format.html do
81
+ format.turbo_stream do
83
82
  # Flash the messages collected from the action
84
83
  flash_messages messages
85
84
 
86
85
  if response[:type] == :redirect
87
- path = response[:path]
88
-
89
- if path.respond_to? :call
90
- path = instance_eval(&path)
91
- end
92
-
93
- redirect_to path, **{allow_other_host: response[:allow_other_host], status: response[:status]}.compact
94
- elsif response[:type] == :reload
86
+ render turbo_stream: turbo_stream.redirect_to(
87
+ Avo::ExecutionContext.new(target: response[:path]).handle,
88
+ nil,
89
+ response[:redirect_args][:turbo_frame],
90
+ **response[:redirect_args].except(:turbo_frame)
91
+ )
92
+ else
95
93
  redirect_back fallback_location: resources_path(resource: @resource)
96
94
  end
97
95
  end
@@ -6,7 +6,6 @@ module Avo
6
6
  Avo::ApplicationController.include Pundit
7
7
  end
8
8
 
9
- include Pagy::Backend
10
9
  include Avo::ApplicationHelper
11
10
  include Avo::UrlHelpers
12
11
  include Avo::Concerns::Breadcrumbs
@@ -81,7 +81,7 @@ module Avo
81
81
  association_name = BaseResource.valid_association_name(@model, params[:related_name])
82
82
 
83
83
  if reflection_class == "HasManyReflection"
84
- @model.send(association_name).destroy @attachment_model
84
+ @model.send(association_name).delete @attachment_model
85
85
  else
86
86
  @model.send("#{association_name}=", nil)
87
87
  end
@@ -65,14 +65,7 @@ module Avo
65
65
  ).apply_query request, @query, filter_value
66
66
  end
67
67
 
68
- extra_pagy_params = {}
69
-
70
- # Reset open filters when a user navigates to a new page
71
- extra_pagy_params[:keep_filters_panel_open] = if params[:keep_filters_panel_open] == "1"
72
- "0"
73
- end
74
-
75
- @pagy, @models = pagy(@query, items: @index_params[:per_page], link_extra: "data-turbo-frame=\"#{params[:turbo_frame]}\"", size: [1, 2, 2, 1], params: extra_pagy_params)
68
+ apply_pagination
76
69
 
77
70
  # Create resources for each model
78
71
  @resources = @models.map do |model|
@@ -504,8 +497,10 @@ module Avo
504
497
  end
505
498
 
506
499
  def destroy_fail_action
500
+ flash[:error] = destroy_fail_message
501
+
507
502
  respond_to do |format|
508
- format.html { redirect_back fallback_location: params[:referrer] || resources_path(resource: @resource, turbo_frame: params[:turbo_frame], view_type: params[:view_type]), error: destroy_fail_message }
503
+ format.turbo_stream { render partial: "avo/partials/flash_alerts" }
509
504
  end
510
505
  end
511
506
 
@@ -541,5 +536,9 @@ module Avo
541
536
  def set_pagy_locale
542
537
  @pagy_locale = locale.to_s || Avo.configuration.locale || "en"
543
538
  end
539
+
540
+ def apply_pagination
541
+ @pagy, @models = @resource.apply_pagination(index_params: @index_params, query: @query)
542
+ end
544
543
  end
545
544
  end
@@ -2,6 +2,9 @@ import 'mapkick/bundle'
2
2
 
3
3
  import { Alert, Popover } from 'tailwindcss-stimulus-components'
4
4
  import { Application } from '@hotwired/stimulus'
5
+ import TurboPower from 'turbo_power'
6
+
7
+ TurboPower.initialize(Turbo.StreamActions)
5
8
 
6
9
  const application = Application.start()
7
10
 
@@ -2,7 +2,7 @@ import { Controller } from '@hotwired/stimulus'
2
2
  import { castBoolean } from '../helpers/cast_boolean'
3
3
 
4
4
  export default class extends Controller {
5
- static targets = ['controllerDiv', 'resourceIds', 'form', 'selectedAllQuery']
5
+ static targets = ['controllerDiv', 'resourceIds', 'submit', 'selectedAllQuery']
6
6
 
7
7
  connect() {
8
8
  this.resourceIdsTarget.value = this.resourceIds
@@ -13,7 +13,7 @@ export default class extends Controller {
13
13
  }
14
14
 
15
15
  if (this.noConfirmation) {
16
- this.formTarget.submit()
16
+ this.submitTarget.click()
17
17
  } else {
18
18
  this.controllerDivTarget.classList.remove('hidden')
19
19
  }
@@ -7,8 +7,7 @@
7
7
  data-resource-id="<%= params[:id] %>"
8
8
  class="hidden text-slate-800"
9
9
  >
10
- <%= form_with model: @model,
11
- scope: 'fields',
10
+ <%= form_with scope: 'fields',
12
11
  url: Avo::Services::URIService.parse(@resource.records_path).append_paths("actions").to_s,
13
12
  local: true,
14
13
  data: @action.class.form_data_attributes do |form|
@@ -1,3 +1,3 @@
1
1
  <%= turbo_stream.append "alerts" do %>
2
- <%= render Avo::FlashAlertsComponent.new flashes: flash %>
2
+ <%= render Avo::FlashAlertsComponent.new flashes: flash.discard %>
3
3
  <% end %>
data/avo.gemspec CHANGED
@@ -40,6 +40,7 @@ Gem::Specification.new do |spec|
40
40
  spec.add_dependency "active_link_to"
41
41
  spec.add_dependency "view_component", ">= 2.54.0"
42
42
  spec.add_dependency "turbo-rails"
43
+ spec.add_dependency "turbo_power", "~> 0.5.0"
43
44
  spec.add_dependency "addressable"
44
45
  spec.add_dependency "meta-tags"
45
46
  spec.add_dependency "dry-initializer"
@@ -3,7 +3,7 @@
3
3
  # The "main" locale.
4
4
  base_locale: en
5
5
  ## All available locales are inferred from the data by default. Alternatively, specify them explicitly:
6
- locales: [en, fr, nb, nn, pt-BR, pt, ro, tr]
6
+ locales: [ar, en, es, fr, nb, nn, pt-BR, pt, ro, tr]
7
7
  ## Reporting locale, default: en. Available: en, ru.
8
8
  # internal_locale: en
9
9
 
@@ -1,4 +1,5 @@
1
1
  require "pagy/extras/trim"
2
+ require "pagy/extras/countless"
2
3
 
3
4
  # For locales without native pagy i18n support
4
5
  def pagy_locale_path(file_name)
@@ -7,6 +8,7 @@ end
7
8
 
8
9
  extra_locales = [
9
10
  {locale: "en"},
11
+ {locale: "es"},
10
12
  {locale: "fr"},
11
13
  {locale: "nb"},
12
14
  {locale: "pt-BR"},
@@ -7,22 +7,18 @@ module Avo
7
7
  class_attribute :confirm_button_label
8
8
  class_attribute :cancel_button_label
9
9
  class_attribute :no_confirmation, default: false
10
- class_attribute :model
11
- class_attribute :view
12
- class_attribute :user
13
- class_attribute :resource
14
10
  class_attribute :standalone, default: false
15
11
  class_attribute :visible
16
12
  class_attribute :may_download_file, default: false
17
13
  class_attribute :turbo
18
14
 
15
+ attr_accessor :view
19
16
  attr_accessor :response
20
17
  attr_accessor :model
21
18
  attr_accessor :resource
22
19
  attr_accessor :user
23
20
  attr_reader :arguments
24
21
 
25
- delegate :view, to: :class
26
22
  delegate :context, to: ::Avo::App
27
23
  delegate :current_user, to: ::Avo::App
28
24
  delegate :params, to: ::Avo::App
@@ -36,19 +32,21 @@ module Avo
36
32
  def form_data_attributes
37
33
  # We can't respond with a file download from Turbo se we disable it on the form
38
34
  if may_download_file
39
- {turbo: turbo || false, remote: false, action_target: :form}
35
+ {turbo: turbo || false, remote: false}
40
36
  else
41
- {turbo: turbo, turbo_frame: :_top, action_target: :form}.compact
37
+ {turbo: turbo, turbo_frame: :_top}.compact
42
38
  end
43
39
  end
44
40
 
45
41
  # We can't respond with a file download from Turbo se we disable close the modal manually after a while (it's a hack, we know)
46
42
  def submit_button_data_attributes
43
+ attributes = { action_target: "submit" }
44
+
47
45
  if may_download_file
48
- {action: "click->modal#delayedClose"}
49
- else
50
- {}
46
+ attributes[:action] = "click->modal#delayedClose"
51
47
  end
48
+
49
+ attributes
52
50
  end
53
51
  end
54
52
 
@@ -59,10 +57,10 @@ module Avo
59
57
  end
60
58
 
61
59
  def initialize(model: nil, resource: nil, user: nil, view: nil, arguments: {})
62
- self.class.model = model
63
- self.class.resource = resource
64
- self.class.user = user
65
- self.class.view = view
60
+ @model = model
61
+ @resource = resource
62
+ @user = user
63
+ @view = view
66
64
  @arguments = arguments
67
65
 
68
66
  self.class.message ||= I18n.t("avo.are_you_sure_you_want_to_run_this_option")
@@ -75,23 +73,12 @@ module Avo
75
73
 
76
74
  def get_message
77
75
  if self.class.message.respond_to? :call
78
- Avo::Hosts::ResourceRecordHost.new(block: self.class.message, record: self.class.model, resource: self.class.resource).handle
76
+ Avo::Hosts::ResourceRecordHost.new(block: self.class.message, record: @model, resource: @resource).handle
79
77
  else
80
78
  self.class.message
81
79
  end
82
80
  end
83
81
 
84
- def get_attributes_for_action
85
- get_fields.map do |field|
86
- default_value = if field.default.respond_to? :call
87
- Avo::Hosts::ResourceViewRecordHost.new(block: field.default, record: self.class.model, view: view, resource: self.class.resource).handle
88
- else
89
- field.default
90
- end
91
- [field.id, field.value || default_value]
92
- end.to_h
93
- end
94
-
95
82
  def handle_action(**args)
96
83
  models, fields, current_user, resource = args.values_at(:models, :fields, :current_user, :resource)
97
84
  # Fetching the field definitions and not the actual fields (get_fields) because they will break if the user uses a `visible` block and adds a condition using the `params` variable. The params are different in the show method and the handle method.
@@ -144,8 +131,8 @@ module Avo
144
131
  block: visible,
145
132
  params: params,
146
133
  parent_resource: parent_resource,
147
- resource: self.class.resource,
148
- view: self.class.view,
134
+ resource: @resource,
135
+ view: @view,
149
136
  arguments: arguments
150
137
  ).handle
151
138
  end
@@ -197,10 +184,9 @@ module Avo
197
184
  self
198
185
  end
199
186
 
200
- def redirect_to(path = nil, allow_other_host: nil, status: nil, &block)
187
+ def redirect_to(path = nil, **args, &block)
201
188
  response[:type] = :redirect
202
- response[:allow_other_host] = allow_other_host
203
- response[:status] = status
189
+ response[:redirect_args] = args
204
190
  response[:path] = if block.present?
205
191
  block
206
192
  else
@@ -8,6 +8,7 @@ module Avo
8
8
  include Avo::Concerns::HasEditableControls
9
9
  include Avo::Concerns::HasStimulusControllers
10
10
  include Avo::Concerns::ModelClassConstantized
11
+ include Avo::Concerns::Pagination
11
12
 
12
13
  delegate :view_context, to: ::Avo::App
13
14
  delegate :current_user, to: ::Avo::App
@@ -0,0 +1,53 @@
1
+ module Avo
2
+ module Concerns
3
+ module Pagination
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ include Pagy::Backend
8
+
9
+ class_attribute :pagination, default: {}
10
+
11
+ PAGINATION_METHOD = {
12
+ default: :pagy,
13
+ countless: :pagy_countless,
14
+ } unless defined? PAGINATION_METHOD
15
+
16
+ PAGINATION_DEFAULTS = {
17
+ type: :default,
18
+ size: [1, 2, 2, 1],
19
+ } unless defined? PAGINATION_DEFAULTS
20
+ end
21
+
22
+ def pagination_type
23
+ @pagination_type ||= ActiveSupport::StringInquirer.new(pagination_hash[:type].to_s)
24
+ end
25
+
26
+ def apply_pagination(index_params:, query:)
27
+ extra_pagy_params = {}
28
+
29
+ # Reset open filters when a user navigates to a new page
30
+ extra_pagy_params[:keep_filters_panel_open] = if params[:keep_filters_panel_open] == "1"
31
+ "0"
32
+ end
33
+
34
+ send PAGINATION_METHOD[pagination_type.to_sym],
35
+ query,
36
+ items: index_params[:per_page],
37
+ link_extra: "data-turbo-frame=\"#{params[:turbo_frame]}\"",
38
+ params: extra_pagy_params,
39
+ size: pagination_hash[:size]
40
+ end
41
+
42
+ private
43
+
44
+ def pagination_hash
45
+ @pagination ||= PAGINATION_DEFAULTS.merge Avo::ExecutionContext.new(
46
+ target: pagination,
47
+ resource: self,
48
+ view: @view
49
+ ).handle
50
+ end
51
+ end
52
+ end
53
+ end
@@ -99,14 +99,20 @@ module Avo
99
99
  except_on args[:except_on] if args[:except_on].present?
100
100
  end
101
101
 
102
- def hydrate(model: nil, resource: nil, action: nil, view: nil, panel_name: nil, user: nil)
103
- @model = model if model.present?
104
- @view = view if view.present?
105
- @resource = resource if resource.present?
106
- @action = action if action.present?
107
- @user = user if user.present?
108
- @panel_name = panel_name if panel_name.present?
102
+ def hydrate(**kwargs)
103
+ # List of permitted keyword argument keys as symbols
104
+ permited_kwargs_keys = %i[model resource action view panel_name user]
109
105
 
106
+ # Check for unrecognized keys
107
+ unrecognized_keys = kwargs.keys - permited_kwargs_keys
108
+ raise ArgumentError, "Unrecognized argument(s): #{unrecognized_keys.join(', ')}" if unrecognized_keys.any?
109
+
110
+ # Set instance variables with provided values
111
+ kwargs.each do |key, value|
112
+ instance_variable_set("@#{key}", value)
113
+ end
114
+
115
+ # Return self for method chaining, if desired
110
116
  self
111
117
  end
112
118
 
data/lib/avo/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Avo
2
- VERSION = "2.43.0" unless const_defined?(:VERSION)
2
+ VERSION = "2.45.0" unless const_defined?(:VERSION)
3
3
  end
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  ar:
3
3
  avo:
4
- action_ran_successfully: 'تم تنفيذ الأمر بنجاح!'
4
+ action_ran_successfully: تم تنفيذ الأمر بنجاح!
5
5
  actions: أوامر
6
6
  and_x_other_resources: و %{count} موارد أخرى
7
7
  are_you_sure: هل أنت متأكد؟
@@ -10,8 +10,8 @@ ar:
10
10
  attach: ربط
11
11
  attach_and_attach_another: ربط وربط آخر
12
12
  attach_item: ربط %{item}
13
- attachment_class_attached: '%{attachment_class} تم ربط'
14
- attachment_class_detached: '%{attachment_class} تم فصل'
13
+ attachment_class_attached: "%{attachment_class} تم ربط"
14
+ attachment_class_detached: "%{attachment_class} تم فصل"
15
15
  attachment_destroyed: تم حذف المرفق
16
16
  cancel: إلغاء
17
17
  choose_a_country: اختر دولة
@@ -80,6 +80,7 @@ ar:
80
80
  to_top: حرك السجل للأعلى بشكل كامل
81
81
  per_page: لكل صفحة
82
82
  prev_page: الصفحة السابقة
83
+ records_selected_from_all_pages_html: جميع السجلات مختارة من جميع الصفحات
83
84
  remove_selection: إزالة التحديد
84
85
  reset_filters: إعادة تعيين الفلاتر
85
86
  resource_created: تم إنشاء السجل
@@ -121,6 +122,5 @@ ar:
121
122
  zero: لا توجد عناصر إضافية
122
123
  x_records_selected_from_a_total_of_x_html: <span class="font-bold text-gray-700">%{selected}</span> السجلات المحددة في هذه الصفحة من إجمالي<span class="font-bold text-gray-700">%{count}</span>
123
124
  x_records_selected_from_all_pages_html: <span class="font-bold text-gray-700">%{count}</span> السجلات المحددة من كل الصفحات
125
+ x_records_selected_from_page_html: <span class="font-bold text-gray-700">%{selected}</span> السجلات المختارة في هذه الصفحة
124
126
  you_missed_something_check_form: ربما نسيت شيئًا، يرجى التحقق من البيانات.
125
-
126
-
@@ -80,6 +80,7 @@ en:
80
80
  to_top: Move record to top
81
81
  per_page: Per page
82
82
  prev_page: Previous page
83
+ records_selected_from_all_pages_html: All records selected from all pages
83
84
  remove_selection: Remove selection
84
85
  reset_filters: Reset filters
85
86
  resource_created: Record created
@@ -121,4 +122,5 @@ en:
121
122
  zero: no more items
122
123
  x_records_selected_from_a_total_of_x_html: <span class="font-bold text-gray-700">%{selected}</span> records selected on this page from a total of <span class="font-bold text-gray-700">%{count}</span>
123
124
  x_records_selected_from_all_pages_html: <span class="font-bold text-gray-700">%{count}</span> records selected from all pages
125
+ x_records_selected_from_page_html: <span class="font-bold text-gray-700">%{selected}</span> records selected on this page
124
126
  you_missed_something_check_form: You might have missed something. Please check the form.