easy-admin-rails 0.1.15 → 0.2.0

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 (92) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/builds/easy_admin.base.js +254 -18
  3. data/app/assets/builds/easy_admin.base.js.map +4 -4
  4. data/app/assets/builds/easy_admin.css +112 -18
  5. data/app/components/easy_admin/base_component.rb +1 -0
  6. data/app/components/easy_admin/form_tabs_component.rb +5 -2
  7. data/app/components/easy_admin/navbar_component.rb +5 -1
  8. data/app/components/easy_admin/permissions/user_role_assignment_component.rb +254 -0
  9. data/app/components/easy_admin/permissions/user_role_permissions_component.rb +186 -0
  10. data/app/components/easy_admin/resources/index_component.rb +1 -4
  11. data/app/components/easy_admin/sidebar_component.rb +67 -2
  12. data/app/controllers/easy_admin/application_controller.rb +131 -1
  13. data/app/controllers/easy_admin/batch_actions_controller.rb +27 -0
  14. data/app/controllers/easy_admin/concerns/belongs_to_editing.rb +201 -0
  15. data/app/controllers/easy_admin/concerns/inline_field_editing.rb +297 -0
  16. data/app/controllers/easy_admin/concerns/resource_authorization.rb +55 -0
  17. data/app/controllers/easy_admin/concerns/resource_filtering.rb +178 -0
  18. data/app/controllers/easy_admin/concerns/resource_loading.rb +149 -0
  19. data/app/controllers/easy_admin/concerns/resource_pagination.rb +135 -0
  20. data/app/controllers/easy_admin/dashboard_controller.rb +2 -1
  21. data/app/controllers/easy_admin/dashboards_controller.rb +6 -40
  22. data/app/controllers/easy_admin/resources_controller.rb +13 -762
  23. data/app/controllers/easy_admin/row_actions_controller.rb +25 -0
  24. data/app/helpers/easy_admin/fields_helper.rb +61 -9
  25. data/app/javascript/easy_admin/controllers/event_emitter_controller.js +2 -4
  26. data/app/javascript/easy_admin/controllers/infinite_scroll_controller.js +0 -10
  27. data/app/javascript/easy_admin/controllers/jsoneditor_controller.js +1 -4
  28. data/app/javascript/easy_admin/controllers/permission_toggle_controller.js +227 -0
  29. data/app/javascript/easy_admin/controllers/role_preview_controller.js +93 -0
  30. data/app/javascript/easy_admin/controllers/select_field_controller.js +1 -2
  31. data/app/javascript/easy_admin/controllers/settings_button_controller.js +1 -2
  32. data/app/javascript/easy_admin/controllers/settings_sidebar_controller.js +1 -4
  33. data/app/javascript/easy_admin/controllers/turbo_stream_redirect.js +0 -2
  34. data/app/javascript/easy_admin/controllers.js +5 -1
  35. data/app/models/easy_admin/admin_user.rb +6 -0
  36. data/app/policies/admin_user_policy.rb +36 -0
  37. data/app/policies/application_policy.rb +83 -0
  38. data/app/views/easy_admin/application/authorization_failure.turbo_stream.erb +8 -0
  39. data/app/views/easy_admin/dashboards/card.html.erb +5 -0
  40. data/app/views/easy_admin/dashboards/card.turbo_stream.erb +7 -0
  41. data/app/views/easy_admin/dashboards/card_error.html.erb +3 -0
  42. data/app/views/easy_admin/dashboards/card_error.turbo_stream.erb +5 -0
  43. data/app/views/easy_admin/dashboards/show.turbo_stream.erb +7 -0
  44. data/app/views/easy_admin/resources/belongs_to_edit_attached.html.erb +6 -0
  45. data/app/views/easy_admin/resources/belongs_to_edit_attached.turbo_stream.erb +8 -0
  46. data/app/views/easy_admin/resources/belongs_to_reattach.html.erb +5 -0
  47. data/app/views/easy_admin/resources/edit.html.erb +1 -1
  48. data/app/views/easy_admin/resources/edit_field.html.erb +5 -0
  49. data/app/views/easy_admin/resources/edit_field.turbo_stream.erb +7 -0
  50. data/app/views/easy_admin/resources/index.html.erb +1 -1
  51. data/app/views/easy_admin/resources/index_frame.html.erb +8 -142
  52. data/app/views/easy_admin/resources/update_belongs_to_attached.turbo_stream.erb +25 -0
  53. data/app/views/layouts/easy_admin/application.html.erb +15 -2
  54. data/config/initializers/easy_admin_permissions.rb +73 -0
  55. data/db/seeds/easy_admin_permissions.rb +121 -0
  56. data/lib/easy-admin-rails.rb +2 -0
  57. data/lib/easy_admin/permissions/component.rb +168 -0
  58. data/lib/easy_admin/permissions/configuration.rb +37 -0
  59. data/lib/easy_admin/permissions/controller.rb +164 -0
  60. data/lib/easy_admin/permissions/dsl.rb +180 -0
  61. data/lib/easy_admin/permissions/models.rb +44 -0
  62. data/lib/easy_admin/permissions/permission_denied_component.rb +121 -0
  63. data/lib/easy_admin/permissions/resource_permissions.rb +231 -0
  64. data/lib/easy_admin/permissions/role_definition.rb +45 -0
  65. data/lib/easy_admin/permissions/role_denied_component.rb +159 -0
  66. data/lib/easy_admin/permissions/role_dsl.rb +73 -0
  67. data/lib/easy_admin/permissions/user_extensions.rb +129 -0
  68. data/lib/easy_admin/permissions.rb +113 -0
  69. data/lib/easy_admin/resource/base.rb +119 -0
  70. data/lib/easy_admin/resource/configuration.rb +148 -0
  71. data/lib/easy_admin/resource/dsl.rb +117 -0
  72. data/lib/easy_admin/resource/field_registry.rb +189 -0
  73. data/lib/easy_admin/resource/form_builder.rb +123 -0
  74. data/lib/easy_admin/resource/layout_builder.rb +249 -0
  75. data/lib/easy_admin/resource/scope_manager.rb +252 -0
  76. data/lib/easy_admin/resource/show_builder.rb +359 -0
  77. data/lib/easy_admin/resource.rb +8 -835
  78. data/lib/easy_admin/resource_modules.rb +11 -0
  79. data/lib/easy_admin/version.rb +1 -1
  80. data/lib/generators/easy_admin/permissions/install_generator.rb +90 -0
  81. data/lib/generators/easy_admin/permissions/templates/initializers/permissions.rb +37 -0
  82. data/lib/generators/easy_admin/permissions/templates/migrations/create_permission_tables.rb +27 -0
  83. data/lib/generators/easy_admin/permissions/templates/migrations/update_users_for_permissions.rb +6 -0
  84. data/lib/generators/easy_admin/permissions/templates/models/permission.rb +9 -0
  85. data/lib/generators/easy_admin/permissions/templates/models/role.rb +9 -0
  86. data/lib/generators/easy_admin/permissions/templates/models/role_permission.rb +9 -0
  87. data/lib/generators/easy_admin/permissions/templates/models/user_role.rb +9 -0
  88. data/lib/generators/easy_admin/permissions/templates/policies/application_policy.rb +47 -0
  89. data/lib/generators/easy_admin/permissions/templates/policies/user_policy.rb +36 -0
  90. data/lib/generators/easy_admin/permissions/templates/seeds/permissions.rb +89 -0
  91. metadata +62 -5
  92. data/db/migrate/20250101000001_create_easy_admin_admin_users.rb +0 -45
@@ -0,0 +1,135 @@
1
+ module EasyAdmin
2
+ module Concerns
3
+ # ResourcePagination concern handles pagination and related logic
4
+ # Provides methods for applying pagination with pagy gem
5
+ module ResourcePagination
6
+ extend ActiveSupport::Concern
7
+
8
+ private
9
+
10
+ # Apply pagination to records using Pagy
11
+ def apply_pagination(records)
12
+ # Apply pagination using Pagy with resource-specific configuration
13
+ items_per_page = @resource_class.respond_to?(:items_per_page) ? @resource_class.items_per_page : 20
14
+
15
+ # Reset to page 1 if filtering/searching is applied to avoid overflow
16
+ current_page = if has_active_filters?
17
+ 1
18
+ else
19
+ params[:page] || 1
20
+ end
21
+
22
+ pagination_options = {
23
+ items: items_per_page,
24
+ limit: items_per_page,
25
+ page: current_page,
26
+ overflow: :last_page # Handle overflow by redirecting to last valid page
27
+ }
28
+
29
+ # Use countless pagination if enabled for performance
30
+ if @resource_class.respond_to?(:countless_enabled?) && @resource_class.countless_enabled?
31
+ pagy_countless(records, **pagination_options)
32
+ else
33
+ pagy(records, **pagination_options)
34
+ end
35
+ end
36
+
37
+ # Setup sorting parameters with defaults
38
+ def setup_sorting_params
39
+ # Set up data needed for both HTML and turbo stream
40
+ # Default to id DESC if no sort params provided
41
+ sort_field = params[:sort] || 'id'
42
+ sort_direction = params[:direction] || (params[:sort] ? 'asc' : 'desc')
43
+
44
+ [sort_field, sort_direction]
45
+ end
46
+
47
+ # Set current sorting state for views
48
+ def set_current_sorting_state(sort_field, sort_direction)
49
+ @current_sort_field = sort_field
50
+ @current_sort_direction = sort_direction
51
+ @current_period = params[:period]
52
+ end
53
+
54
+ # Build Turbo Stream response for infinite scroll
55
+ def build_infinite_scroll_turbo_stream
56
+ # For infinite scroll - append new rows to existing table
57
+ table_rows_html = @records.map do |record|
58
+ EasyAdmin::Resources::TableRowComponent.new(
59
+ record: record,
60
+ resource_class: @resource_class
61
+ ).call
62
+ end.join.html_safe
63
+
64
+ current_params = params.permit(:search, :scope, :sort, :direction, :period, :page, q: {})
65
+
66
+ [
67
+ turbo_stream.append("records-container", table_rows_html),
68
+ turbo_stream.replace("infinite-scroll-container", EasyAdmin::InfiniteScrollComponent.new(
69
+ pagy: @pagy,
70
+ resource_class: @resource_class,
71
+ current_params: current_params,
72
+ current_path: request.path
73
+ ).call),
74
+ turbo_stream.replace("combined-filters", EasyAdmin::CombinedFiltersComponent.new(
75
+ resource_class: @resource_class,
76
+ current_params: current_params,
77
+ search_params: params[:q] || {},
78
+ current_period: @current_period
79
+ ).call)
80
+ ]
81
+ end
82
+
83
+ # Prepare pagination data for index action
84
+ def prepare_index_pagination_data
85
+ sort_field, sort_direction = setup_sorting_params
86
+
87
+ # Handle scope filtering
88
+ @current_scope = determine_current_scope
89
+
90
+ # Only calculate scope counts for HTML requests, not for infinite scroll (turbo_stream)
91
+ if @resource_class.has_scopes? && !request.format.turbo_stream?
92
+ @scope_counts = calculate_scope_counts
93
+ end
94
+
95
+ # Build filtered records
96
+ @records = build_filtered_records(sort_field, sort_direction)
97
+
98
+ # Apply pagination
99
+ @pagy, @records = apply_pagination(@records)
100
+
101
+ # Set current state for views
102
+ set_current_sorting_state(sort_field, sort_direction)
103
+ end
104
+
105
+ # Handle pagination-related parameters
106
+ def pagination_params
107
+ params.permit(:search, :scope, :sort, :direction, :period, :page, q: {})
108
+ end
109
+
110
+ # Check if we're on first page
111
+ def first_page?
112
+ !params[:page].present? || params[:page].to_i <= 1
113
+ end
114
+
115
+ # Check if pagination should reset due to filtering
116
+ def should_reset_pagination?
117
+ has_active_filters? && !first_page?
118
+ end
119
+
120
+ # Get pagination info for views
121
+ def pagination_info
122
+ return {} unless @pagy
123
+
124
+ {
125
+ current_page: @pagy.page,
126
+ total_pages: @pagy.pages,
127
+ total_count: @pagy.count,
128
+ per_page: @pagy.items,
129
+ from: @pagy.from,
130
+ to: @pagy.to
131
+ }
132
+ end
133
+ end
134
+ end
135
+ end
@@ -1,6 +1,7 @@
1
1
  module EasyAdmin
2
2
  class DashboardController < ApplicationController
3
+ # Skip ActionPolicy authorization for dashboard
3
4
  def index
4
5
  end
5
6
  end
6
- end
7
+ end
@@ -7,16 +7,7 @@ module EasyAdmin
7
7
 
8
8
  respond_to do |format|
9
9
  format.html
10
- format.turbo_stream do
11
- render turbo_stream: turbo_stream.replace(
12
- "dashboard-grid",
13
- EasyAdmin::Dashboards::ShowComponent.new(
14
- dashboard_class: @dashboard_class,
15
- params: dashboard_params,
16
- request_path: request.path
17
- ).call
18
- )
19
- end
10
+ format.turbo_stream
20
11
  format.json { render json: dashboard_data }
21
12
  end
22
13
  end
@@ -33,42 +24,17 @@ module EasyAdmin
33
24
  @card_data = @dashboard_instance.card_data(@card[:name])
34
25
 
35
26
  respond_to do |format|
36
- format.html do
37
- render plain: EasyAdmin::Dashboards::CardStreamComponent.new(
38
- card: @card,
39
- card_data: @card_data,
40
- dashboard_class: @dashboard_class
41
- ).call
42
- end
43
- format.turbo_stream do
44
- render turbo_stream: turbo_stream.replace(
45
- "card_#{@card[:name]}",
46
- EasyAdmin::Dashboards::CardStreamComponent.new(
47
- card: @card,
48
- card_data: @card_data,
49
- dashboard_class: @dashboard_class
50
- ).call
51
- )
52
- end
27
+ format.html
28
+ format.turbo_stream
53
29
  format.json { render json: @card_data }
54
30
  end
55
31
  rescue => e
56
32
  Rails.logger.error "Dashboard card error: #{e.message}"
33
+ @error_message = e.message
57
34
 
58
35
  respond_to do |format|
59
- format.html do
60
- render plain: view_context.turbo_frame_tag("card_#{params[:card_name]}") do
61
- EasyAdmin::Dashboards::CardErrorComponent.new(error: e.message).call
62
- end
63
- end
64
- format.turbo_stream do
65
- render turbo_stream: turbo_stream.replace(
66
- "card_#{params[:card_name]}",
67
- view_context.turbo_frame_tag("card_#{params[:card_name]}") do
68
- EasyAdmin::Dashboards::CardErrorComponent.new(error: e.message).call
69
- end
70
- )
71
- end
36
+ format.html { render template: 'easy_admin/dashboards/card_error' }
37
+ format.turbo_stream { render template: 'easy_admin/dashboards/card_error' }
72
38
  format.json { render json: { error: e.message }, status: :server_error }
73
39
  end
74
40
  end