flexi_admin 0.0.5 → 0.0.6

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 (74) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +254 -18
  3. data/lib/flexi_admin/components/helpers/action_helper.rb +21 -0
  4. data/lib/flexi_admin/components/helpers/frontend_helper.rb +23 -0
  5. data/lib/flexi_admin/components/helpers/link_helper.rb +35 -2
  6. data/lib/flexi_admin/components/helpers/resource_helper.rb +79 -14
  7. data/lib/flexi_admin/components/helpers/url_helper.rb +15 -0
  8. data/lib/flexi_admin/components/nav/breadcrumbs_component.html.slim +13 -0
  9. data/lib/flexi_admin/components/nav/breadcrumbs_component.rb +86 -0
  10. data/lib/flexi_admin/components/resource/autocomplete_component.html.slim +19 -7
  11. data/lib/flexi_admin/components/resource/autocomplete_component.rb +41 -11
  12. data/lib/flexi_admin/components/resource/button_select_component.html.slim +2 -2
  13. data/lib/flexi_admin/components/resource/button_select_component.rb +8 -1
  14. data/lib/flexi_admin/components/resource/filter_component.html.slim +47 -0
  15. data/lib/flexi_admin/components/resource/filter_component.rb +51 -0
  16. data/lib/flexi_admin/components/resource/form_component.rb +16 -1
  17. data/lib/flexi_admin/components/resource/form_element_component.rb +1 -1
  18. data/lib/flexi_admin/components/resource/form_mixin.rb +186 -42
  19. data/lib/flexi_admin/components/resource/link_action_component.html.slim +2 -2
  20. data/lib/flexi_admin/components/resource/link_action_component.rb +3 -2
  21. data/lib/flexi_admin/components/resource/view_component.html.slim +14 -4
  22. data/lib/flexi_admin/components/resource/view_component.rb +11 -2
  23. data/lib/flexi_admin/components/resources/bulk_action/button_component.rb +8 -1
  24. data/lib/flexi_admin/components/resources/bulk_action/modal_component.html.slim +21 -15
  25. data/lib/flexi_admin/components/resources/bulk_action/modal_component.rb +16 -8
  26. data/lib/flexi_admin/components/resources/bulk_action/row_action_button_component.html.slim +16 -0
  27. data/lib/flexi_admin/components/resources/bulk_action/row_action_button_component.rb +78 -0
  28. data/lib/flexi_admin/components/resources/bulk_action/row_actions_dropdown_component.html.slim +15 -0
  29. data/lib/flexi_admin/components/resources/bulk_action/row_actions_dropdown_component.rb +33 -0
  30. data/lib/flexi_admin/components/resources/grid_view/card_component.html.slim +4 -1
  31. data/lib/flexi_admin/components/resources/grid_view/card_component.rb +4 -1
  32. data/lib/flexi_admin/components/resources/grid_view/grid_component.html.slim +3 -1
  33. data/lib/flexi_admin/components/resources/grid_view/grid_component.rb +4 -2
  34. data/lib/flexi_admin/components/resources/grid_view_component.rb +7 -2
  35. data/lib/flexi_admin/components/resources/index_page_component.html.slim +5 -4
  36. data/lib/flexi_admin/components/resources/index_page_component.rb +1 -0
  37. data/lib/flexi_admin/components/resources/list_view/table_component.html.slim +1 -1
  38. data/lib/flexi_admin/components/resources/list_view_component.rb +2 -1
  39. data/lib/flexi_admin/components/resources/pagination_component.html.slim +51 -39
  40. data/lib/flexi_admin/components/resources/pagination_component.rb +52 -47
  41. data/lib/flexi_admin/components/resources/switch_view_component.html.slim +2 -2
  42. data/lib/flexi_admin/components/resources/view_component.html.slim +15 -6
  43. data/lib/flexi_admin/components/shared/medium_component.html.slim +1 -1
  44. data/lib/flexi_admin/components/shared/table/header_item_component.html.slim +1 -1
  45. data/lib/flexi_admin/components/shared/table/header_item_component.rb +59 -61
  46. data/lib/flexi_admin/components/shared/tabs_component.html.slim +26 -0
  47. data/lib/flexi_admin/components/shared/tabs_component.rb +68 -0
  48. data/lib/flexi_admin/components.rb +11 -3
  49. data/lib/flexi_admin/config.rb +21 -3
  50. data/lib/flexi_admin/controllers/modals_controller.rb +4 -2
  51. data/lib/flexi_admin/controllers/resources_controller.rb +246 -51
  52. data/lib/flexi_admin/engine.rb +4 -0
  53. data/lib/flexi_admin/helpers/application_helper.rb +3 -0
  54. data/lib/flexi_admin/javascript/controllers/add_row_controller.js +118 -0
  55. data/lib/flexi_admin/javascript/controllers/autocomplete_controller.js +17 -1
  56. data/lib/flexi_admin/javascript/controllers/bulk_action_controller.js +192 -33
  57. data/lib/flexi_admin/javascript/controllers/copy_to_clipboard_controller.js +16 -0
  58. data/lib/flexi_admin/javascript/controllers/datalist_controller.js +1 -1
  59. data/lib/flexi_admin/javascript/controllers/delete_controller.js +40 -0
  60. data/lib/flexi_admin/javascript/controllers/expandable_field_controller.js +15 -0
  61. data/lib/flexi_admin/javascript/controllers/filter_auto_submit_controller.js +93 -0
  62. data/lib/flexi_admin/javascript/controllers/index.js +18 -0
  63. data/lib/flexi_admin/javascript/controllers/pagination_controller.js +8 -0
  64. data/lib/flexi_admin/javascript/controllers/tabs_controller.js +24 -0
  65. data/lib/flexi_admin/models/concerns/application_resource.rb +6 -0
  66. data/lib/flexi_admin/models/concerns/parentable.rb +3 -0
  67. data/lib/flexi_admin/models/context_params.rb +35 -10
  68. data/lib/flexi_admin/models/resources/context.rb +4 -0
  69. data/lib/flexi_admin/routes.rb +7 -1
  70. data/lib/flexi_admin/services/create_resource.rb +6 -6
  71. data/lib/flexi_admin/version.rb +1 -1
  72. data/lib/flexi_admin/views/shared/_reload_frame.slim +19 -0
  73. data/lib/flexi_admin.rb +0 -3
  74. metadata +171 -10
@@ -5,12 +5,13 @@ module FlexiAdmin::Components::Resource
5
5
  extend FlexiAdmin::Components::Helpers::ActionButtonHelper
6
6
  include FlexiAdmin::Components::Helpers::IconHelper
7
7
 
8
- attr_reader :label, :path, :options
8
+ attr_reader :label, :path, :options, :disabled
9
9
 
10
- def initialize(label, path, **options)
10
+ def initialize(label, path, disabled: false, **options)
11
11
  @label = label
12
12
  @path = path
13
13
  @options = options
14
+ @disabled = disabled
14
15
  end
15
16
  end
16
17
  end
@@ -3,7 +3,7 @@
3
3
  .d-flex.justify-content-between.align-items-center.sticky-top.top-0.py-3.bg-white
4
4
  .d-flex.align-items-center
5
5
  .d-flex.flex-column
6
- h1 = resource.title
6
+ h1 = title
7
7
  / = render FlexiAdmin::Components::Nav::FloatingTocComponent.new
8
8
 
9
9
  // Floating navigation
@@ -14,13 +14,23 @@
14
14
  .btn-group
15
15
  .btn.btn-outline-primary [data-controller="form"
16
16
  data-form-resource-path-value="#{edit_resource_path(resource)}"
17
- data-action="click->form#enable"]
17
+ data-action="click->form#enable"
18
+ class=("disabled btn-with-tooltip" if disable_buttons)
19
+ disabled=("disabled" if disable_buttons)
20
+ data-tooltip=(disabled_message if disable_buttons)]
18
21
  i.bi.bi-pencil-square
19
- .btn.btn-outline-danger
22
+ .btn.btn-outline-danger [data-controller="delete"
23
+ data-delete-resource-path-value="#{resource_path(resource)}"
24
+ data-delete-confirm-message-value="#{delete_confirm_message || "Are you sure you want to delete this #{resource.class.model_name.human.downcase}?"}"
25
+ data-delete-disabled-value="#{disable_buttons ? 'true' : 'false'}"
26
+ data-action="click->delete#delete"
27
+ class=("disabled btn-with-tooltip" if disable_buttons)
28
+ disabled=("disabled" if disable_buttons)
29
+ data-tooltip=(disabled_message if disable_buttons)]
20
30
  i.bi.bi-trash
21
31
 
22
32
  .row.g-0.my-2.mb-4
23
33
  .col-12.col-md-8
24
34
  = form
25
35
 
26
- = content
36
+ = content
@@ -5,18 +5,27 @@ module FlexiAdmin::Components::Resource
5
5
  include FlexiAdmin::Components::Helpers::ResourceHelper
6
6
  include FlexiAdmin::Components::Helpers::ActionHelper
7
7
 
8
- attr_reader :context, :resource
8
+ attr_reader :context, :resource, :disable_buttons, :disabled_message, :delete_confirm_message
9
9
 
10
10
  renders_one :form
11
11
  renders_one :actions
12
12
 
13
- def initialize(context)
13
+ def initialize(context, disable_buttons: nil, disabled_message: nil, delete_confirm_message: nil)
14
14
  @context = context
15
15
  @resource = context.resource
16
+ @disable_buttons = disable_buttons
17
+ @disabled_message = disabled_message
18
+ @delete_confirm_message = delete_confirm_message
16
19
  end
17
20
 
18
21
  def divider
19
22
  content_tag :div, "", class: "dropdown-divider"
20
23
  end
24
+
25
+ def title
26
+ resource.title
27
+ rescue NoMethodError
28
+ "#{resource.class.name}: title method not implemented"
29
+ end
21
30
  end
22
31
  end
@@ -23,7 +23,14 @@ module FlexiAdmin::Components::Resources::BulkAction
23
23
  end
24
24
 
25
25
  def scoped_url_with_modal_id
26
- main_app.admin_modals_path(kind: modal_class.modal_id, **context.to_params)
26
+ path = namespaced_path("flexi_admin", "modals")
27
+ if route_exists_in_main_app?(path)
28
+ main_app.send(path, kind: modal_class.modal_id,
29
+ **context.to_params)
30
+ else
31
+ helpers.send(path,
32
+ kind: modal_class.modal_id, **context.to_params)
33
+ end
27
34
  end
28
35
  end
29
36
  end
@@ -5,20 +5,25 @@ div.modal.fade id="#{context.options[:modal_id]}" tabindex="-1"
5
5
  h1.modal-title.fs-5 = context.options[:title]
6
6
  button.btn-close type="button" data-bs-dismiss="modal" aria-label="Close"
7
7
 
8
- div.modal-body
9
- = modal_form
8
+ fieldset.modal-fieldset disabled=context.options[:disabled]
9
+ div.modal-body
10
+ - if context.options[:errors].present?
11
+ div.alert.alert-danger
12
+ = context.options[:errors].messages.values.flatten.join(', ')
13
+ = modal_form
10
14
 
11
- div.modal-footer.d-flex.justify-content-between.align-items-center
12
- .d-flex.justify-content-start.gap-3
13
- button.btn.btn-primary [type="submit"
14
- data-action="click->bulk-action#submitForm"]
15
- | Spustit
16
- button.btn.btn-secondary [type="button"
17
- data-bs-dismiss="modal"]
18
- | Zrušit
19
- span
20
- |> vybraných položek:
21
- span.count
15
+ - unless context.options[:skip_confirmation_buttons]
16
+ div.modal-footer.d-flex.justify-content-between.align-items-center
17
+ .d-flex.justify-content-start.gap-3
18
+ button.btn.btn-primary [type="submit"
19
+ data-action="click->bulk-action#submitForm"]
20
+ | Spustit
21
+ button.btn.btn-secondary [type="button"
22
+ data-bs-dismiss="modal"]
23
+ | Zrušit
24
+ span
25
+ |> vybraných položek:
26
+ span.count
22
27
 
23
28
  javascript:
24
29
  var modal = new window.bootstrap.Modal(document.getElementById('#{context.options[:modal_id]}'));
@@ -27,6 +32,7 @@ div.modal.fade id="#{context.options[:modal_id]}" tabindex="-1"
27
32
  { detail:
28
33
  {
29
34
  modalId: '#{context.options[:modal_id]}',
30
- scope: '#{context.scope}'
35
+ scope: '#{context.scope}',
36
+ selectedIds: #{{(context.params.request_params[:selected_ids] || []).to_json}}
31
37
  }
32
- }));
38
+ }));
@@ -9,30 +9,38 @@ module FlexiAdmin::Components::Resources::BulkAction
9
9
  attr_accessor :class_name
10
10
  end
11
11
 
12
- attr_reader :context
12
+ attr_reader :context, :extra_options
13
13
 
14
14
  renders_one :modal_form
15
15
 
16
- def initialize(context = nil)
16
+ def initialize(context = nil, **extra_options)
17
17
  @context = context
18
18
 
19
- add_context_options(@context)
19
+ add_context_options(context)
20
+ extra_options.each do |key, value|
21
+ context.options[key] = value
22
+ end
20
23
  super(nil, disabled: false)
21
24
  end
22
25
 
23
- def modal(context, &block)
24
- render FlexiAdmin::Components::Resources::BulkAction::ModalComponent.new(context) do |component|
26
+ def modal(context, **options,&block)
27
+ render FlexiAdmin::Components::Resources::BulkAction::ModalComponent.new(context, **options) do |component|
25
28
  component.with_modal_form(&block)
26
29
  end
27
30
  end
28
31
 
29
- def form(url: self.class.path, method: :post, **html_options, &block)
30
- super(url:, css_class: 'modalForm section', method:, **html_options, &block)
32
+ def form(url: self.class.path, method: :post, label_col: 'col-md-3', field_col: 'col-md-9', **html_options, &block)
33
+ super(url:, css_class: 'modalForm section', method:, label_col:, field_col:, **html_options, &block)
31
34
  end
32
35
 
33
36
  # /observation_images/bulk_action
34
37
  def self.path
35
- resource = (self.class_name&.to_s || to_s).split('::').first.underscore.gsub('/', '-')
38
+ class_name = self.class_name&.to_s || to_s
39
+ resource = if class_name.downcase.start_with?(FlexiAdmin::Config.configuration.namespace.downcase)
40
+ class_name.split('::')[1].underscore.gsub('/', '-')
41
+ else
42
+ class_name.underscore.gsub('/', '-')
43
+ end
36
44
  "/#{resource.pluralize}/bulk_action"
37
45
  end
38
46
 
@@ -0,0 +1,16 @@
1
+ - if dropdown_mode?
2
+ - if disabled?
3
+ - attrs = { 'aria-disabled' => 'true', 'class' => 'text-muted' }
4
+ - else
5
+ - attrs = { href: "#", 'data-action' => "click->bulk-action#requestModal", 'data-scope' => context.scope, 'data-url-with-id' => scoped_url_with_modal_id }
6
+ a.dropdown-item *attrs
7
+ - if show_icon?
8
+ i.bi.me-2 class="#{button_icon_class}"
9
+ = button_text
10
+ - else
11
+ - attrs = { 'class' => css_classes, 'data-action' => "click->bulk-action#requestModal", 'data-scope' => context.scope, 'data-url-with-id' => scoped_url_with_modal_id }
12
+ - attrs['disabled'] = 'disabled' if disabled?
13
+ button *attrs
14
+ - if show_icon?
15
+ i.bi.me-2 class="#{button_icon_class}"
16
+ = button_text
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FlexiAdmin::Components::Resources::BulkAction
4
+ # Component for rendering action buttons on individual rows (not bulk selection)
5
+ # Opens a modal for a single item action
6
+ class RowActionButtonComponent < FlexiAdmin::Components::BaseComponent
7
+ include FlexiAdmin::Components::Helpers::UrlHelper
8
+ include FlexiAdmin::Components::Helpers::IconHelper
9
+
10
+ attr_reader :item, :context, :modal_class, :options, :dropdown_mode, :hide_icon, :disabled
11
+
12
+ def initialize(item, context, modal_class, dropdown: false, hide_icon: false, disabled: false, **options)
13
+ super(nil)
14
+ @item = item
15
+ @context = context
16
+ @modal_class = modal_class
17
+ @dropdown_mode = dropdown
18
+ @hide_icon = hide_icon
19
+ @disabled = disabled
20
+ @options = options
21
+ end
22
+
23
+ def dropdown_mode?
24
+ @dropdown_mode
25
+ end
26
+
27
+ def disabled?
28
+ @disabled
29
+ end
30
+
31
+ def button_text
32
+ modal_class.button_text
33
+ end
34
+
35
+ def button_icon
36
+ modal_class.button_icon
37
+ end
38
+
39
+ def button_icon_class
40
+ modal_class.button_icon_class if button_icon.present?
41
+ end
42
+
43
+ def show_icon?
44
+ !@hide_icon && button_icon.present?
45
+ end
46
+
47
+ def scoped_url_with_modal_id
48
+ path = namespaced_path("flexi_admin", "modals")
49
+
50
+ item_params = context.params.merge(
51
+ selected_ids: [item.id],
52
+ scope: context.scope
53
+ )
54
+
55
+ url_params = {
56
+ kind: modal_class.modal_id,
57
+ **item_params.to_params
58
+ }
59
+
60
+ if route_exists_in_main_app?(path)
61
+ main_app.send(path, url_params)
62
+ else
63
+ helpers.send(path, url_params)
64
+ end
65
+ end
66
+
67
+ def css_classes
68
+ if dropdown_mode?
69
+ classes = %w[dropdown-item]
70
+ else
71
+ classes = %w[btn btn-sm btn-outline-primary]
72
+ end
73
+ classes << "text-muted" if disabled?
74
+ classes.concat(options[:class].split) if options[:class]
75
+ classes.join(" ")
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,15 @@
1
+ .d-flex.gap-2
2
+ - if primary_action?
3
+ = primary_action
4
+
5
+ .dropdown
6
+ button.btn.btn-sm.btn-outline-secondary [type="button"
7
+ id="#{dropdown_id}"
8
+ data-bs-toggle="dropdown"
9
+ aria-expanded="false"]
10
+ i.bi.bi-three-dots-vertical
11
+
12
+ ul.dropdown-menu [aria-labelledby="#{dropdown_id}"]
13
+ - dropdown_actions.each do |action|
14
+ li
15
+ = action
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FlexiAdmin::Components::Resources::BulkAction
4
+ # Component for rendering a dropdown of multiple action buttons for an individual row
5
+ # Useful when you have multiple actions available for a single item
6
+ class RowActionsDropdownComponent < FlexiAdmin::Components::BaseComponent
7
+ attr_reader :item, :context
8
+
9
+ renders_one :primary_action
10
+ renders_many :dropdown_actions
11
+
12
+ def initialize(item, context)
13
+ super(nil)
14
+ @item = item
15
+ @context = context
16
+ end
17
+
18
+ def dropdown_id
19
+ "row-actions-#{item.class.name.parameterize}-#{item.id}"
20
+ end
21
+
22
+ # Helper method to add an action button to the dropdown
23
+ def action_button(modal_class, **options)
24
+ FlexiAdmin::Components::Resources::BulkAction::RowActionButtonComponent.new(
25
+ item,
26
+ context,
27
+ modal_class,
28
+ dropdown: true,
29
+ **options
30
+ )
31
+ end
32
+ end
33
+ end
@@ -1,5 +1,8 @@
1
1
  .card style="width: 18rem;"
2
- = render(FlexiAdmin::Components::Actions::CheckboxComponent.new(id: resource.id, scope: resource.class.name.downcase))
2
+ = render(FlexiAdmin::Components::Actions::CheckboxComponent.new(id: resource.id, scope: context.scope))
3
+ - if quick_action
4
+ .quick-action
5
+ = quick_action.call(resource)
3
6
  div
4
7
  - if media?
5
8
  = render_media
@@ -5,13 +5,16 @@ module FlexiAdmin::Components::Resources::GridView
5
5
  include FlexiAdmin::Components::Helpers::LinkHelper
6
6
 
7
7
  attr_accessor :resource, :title, :header, :description, :image
8
+ attr_reader :context, :quick_action
8
9
 
9
- def initialize(resource, title, header, description, image)
10
+ def initialize(resource, title, header, description, image, quick_action = nil, context)
10
11
  @resource = resource
11
12
  @title = title
12
13
  @header = header
13
14
  @description = description
14
15
  @image = image
16
+ @quick_action = quick_action
17
+ @context = context
15
18
  end
16
19
 
17
20
  def media_attachment
@@ -7,4 +7,6 @@
7
7
  title_element,
8
8
  header_element,
9
9
  description_element,
10
- image_element)
10
+ image_element,
11
+ quick_action_block,
12
+ context)
@@ -2,14 +2,16 @@
2
2
 
3
3
  module FlexiAdmin::Components::Resources::GridView
4
4
  class GridComponent < FlexiAdmin::Components::BaseComponent
5
- attr_reader :resources, :title_element, :header_element, :description_element, :image_element, :context
5
+ attr_reader :resources, :title_element, :header_element, :description_element,
6
+ :image_element, :quick_action_block, :context
6
7
 
7
- def initialize(resources, title_element, header_element, description_element, image_element, context)
8
+ def initialize(resources, title_element, header_element, description_element, image_element, quick_action_block, context)
8
9
  @resources = resources
9
10
  @title_element = title_element
10
11
  @header_element = header_element
11
12
  @description_element = description_element
12
13
  @image_element = image_element
14
+ @quick_action_block = quick_action_block
13
15
  @context = context
14
16
  end
15
17
  end
@@ -31,7 +31,7 @@ module FlexiAdmin::Components::Resources
31
31
  end
32
32
 
33
33
  attr_reader :context, :resources, :resource
34
- attr_accessor :title_element, :header_element, :description_element, :image_element
34
+ attr_accessor :title_element, :header_element, :description_element, :image_element, :quick_action_block
35
35
 
36
36
  def initialize(context)
37
37
  @context = context
@@ -51,7 +51,8 @@ module FlexiAdmin::Components::Resources
51
51
  def grid
52
52
  render FlexiAdmin::Components::Resources::GridView::GridComponent.new(resources, title_element, header_element,
53
53
  description_element,
54
- image_element, context)
54
+ image_element, quick_action_block,
55
+ context)
55
56
  end
56
57
 
57
58
  def render?
@@ -85,5 +86,9 @@ module FlexiAdmin::Components::Resources
85
86
 
86
87
  self.description_element = Element.new(attribute, value, options)
87
88
  end
89
+
90
+ def quick_action(&block)
91
+ self.quick_action_block = block
92
+ end
88
93
  end
89
94
  end
@@ -4,10 +4,11 @@ h1 = title
4
4
 
5
5
  div data-scope="#{scope}"
6
6
  div.py-3
7
- .d-flex.justify-content-between
7
+ .d-flex
8
8
  - if show_search
9
- div style="width: 330px"
10
- = search
9
+ = search
10
+ - if filter
11
+ = filter
11
12
  div
12
13
  = actions
13
- = content
14
+ = content
@@ -5,6 +5,7 @@ module FlexiAdmin::Components::Resources
5
5
  attr_reader :resources, :context_params, :scope, :title, :show_search, :subtitle
6
6
 
7
7
  renders_one :search
8
+ renders_one :filter
8
9
  renders_one :actions
9
10
 
10
11
  def initialize(resources, context_params:, scope:, show_search: true, title: nil, subtitle: nil)
@@ -5,7 +5,7 @@ flexi-table
5
5
  = render(FlexiAdmin::Components::Actions::CheckboxComponent.new(id: 'all', scope: context.scope, select_all: true))
6
6
 
7
7
  - columns.each do |column|
8
- = render FlexiAdmin::Components::Shared::Table::HeaderItemComponent.new(column)
8
+ = render FlexiAdmin::Components::Shared::Table::HeaderItemComponent.new(column, context: context)
9
9
 
10
10
  - resources.each do |resource|
11
11
  .row.border-top.py-2
@@ -7,6 +7,7 @@ module FlexiAdmin::Components::Resources
7
7
  include FlexiAdmin::Components::Helpers::ValueFormatter
8
8
  include FlexiAdmin::Components::Helpers::Selectable
9
9
  include FlexiAdmin::Components::Helpers::LinkHelper
10
+ include FlexiAdmin::Components::Helpers::ActionHelper
10
11
 
11
12
  class Column < Struct.new(:attribute, :value, :options)
12
13
  def width
@@ -77,4 +78,4 @@ module FlexiAdmin::Components::Resources
77
78
  options.presence || {})
78
79
  end
79
80
  end
80
- end
81
+ end
@@ -1,42 +1,54 @@
1
1
  nav data-controller="pagination"
2
- ul.pagination.m-0.p-0
3
- li.page-item class="#{paginated_resources.previous_page ? '' : 'disabled'}"
4
- - if paginated_resources.previous_page
5
- /= helpers.link_to page_path(paginated_resources.previous_page),
6
- class: 'page-link',
7
- data: { action: 'click->pagination#paginate',
8
- resource_path: page_path(paginated_resources.previous_page) } do
9
- a.page-link [href=page_path(paginated_resources.previous_page)
10
- data-action="click->pagination#paginate"
11
- data-resource-path=page_path(paginated_resources.previous_page)]
12
- '←
13
- - else
14
- span.page-link ←
2
+ .d-flex.justify-content-between.align-items-center
3
+ .pagination-wrapper
4
+ ul.pagination.m-0.p-0
5
+ li.page-item class="#{paginated_resources.previous_page ? '' : 'disabled'}"
6
+ - if paginated_resources.previous_page
7
+ /= helpers.link_to page_path(paginated_resources.previous_page),
8
+ class: 'page-link',
9
+ data: { action: 'click->pagination#paginate',
10
+ resource_path: page_path(paginated_resources.previous_page) } do
11
+ a.page-link [href=page_path(paginated_resources.previous_page)
12
+ data-action="click->pagination#paginate"
13
+ data-resource-path=page_path(paginated_resources.previous_page)]
14
+ '←
15
+ - else
16
+ span.page-link ←
15
17
 
16
- - limited_pages.each do |page|
17
- - if page == paginated_resources.current_page
18
- li.page-item.active
19
- span.page-link = page
20
- - else
21
- li.page-item
22
- /= helpers.link_to page_path(page),
23
- class: 'page-link',
24
- data: { action: 'click->pagination#paginate',
25
- resource_path: page_path(page) } do
26
- a.page-link [href=page_path(page)
27
- data-action="click->pagination#paginate"
28
- data-resource-path=page_path(page)]
29
- = page
18
+ - limited_pages.each do |page|
19
+ - if page == paginated_resources.current_page
20
+ li.page-item.active
21
+ span.page-link = page
22
+ - else
23
+ li.page-item
24
+ /= helpers.link_to page_path(page),
25
+ class: 'page-link',
26
+ data: { action: 'click->pagination#paginate',
27
+ resource_path: page_path(page) } do
28
+ a.page-link [href=page_path(page)
29
+ data-action="click->pagination#paginate"
30
+ data-resource-path=page_path(page)]
31
+ = page
30
32
 
31
- li.page-item class="#{paginated_resources.next_page ? '' : 'disabled'}"
32
- - if paginated_resources.next_page
33
- /= helpers.link_to page_path(paginated_resources.next_page),
34
- class: 'page-link',
35
- data: { action: 'click->pagination#paginate',
36
- resource_path: page_path(paginated_resources.next_page) } do
37
- a.page-link [href=page_path(paginated_resources.next_page)
38
- data-action="click->pagination#paginate"
39
- data-resource-path=page_path(paginated_resources.next_page)]
40
- '→
41
- - else
42
- span.page-link →
33
+ li.page-item class="#{paginated_resources.next_page ? '' : 'disabled'}"
34
+ - if paginated_resources.next_page
35
+ /= helpers.link_to page_path(paginated_resources.next_page),
36
+ class: 'page-link',
37
+ data: { action: 'click->pagination#paginate',
38
+ resource_path: page_path(paginated_resources.next_page) } do
39
+ a.page-link [href=page_path(paginated_resources.next_page)
40
+ data-action="click->pagination#paginate"
41
+ data-resource-path=page_path(paginated_resources.next_page)]
42
+ '→
43
+ - else
44
+ span.page-link →
45
+
46
+ .per-page-selector
47
+ .d-flex.align-items-center.gap-2
48
+ / label.form-label.mb-0.small Per page:
49
+ = select_tag 'per_page',
50
+ options_for_select(FlexiAdmin::Config.configuration.paginate_per_options.map { |opt| [opt, opt] }, per_page || FlexiAdmin::Config.configuration.paginate_per),
51
+ class: 'form-select ms-2',
52
+ style: 'width: auto;',
53
+ data: { action: 'change->pagination#changePerPage',
54
+ 'per-page-path': per_page_path('__PER_PAGE__') }