easy-admin-rails 0.1.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 (203) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +28 -0
  4. data/Rakefile +8 -0
  5. data/app/assets/builds/easy_admin.base.js +43505 -0
  6. data/app/assets/builds/easy_admin.base.js.map +7 -0
  7. data/app/assets/builds/easy_admin.css +6141 -0
  8. data/app/assets/config/easy_admin_manifest.js +1 -0
  9. data/app/assets/images/jsoneditor-icons.svg +749 -0
  10. data/app/assets/stylesheets/easy_admin/application.tailwind.css +390 -0
  11. data/app/components/easy_admin/base_component.rb +35 -0
  12. data/app/components/easy_admin/batch_action_bar_component.rb +125 -0
  13. data/app/components/easy_admin/batch_action_form_component.rb +124 -0
  14. data/app/components/easy_admin/combined_filters_component.rb +232 -0
  15. data/app/components/easy_admin/confirmation_modal_component.rb +61 -0
  16. data/app/components/easy_admin/context_menu_component.rb +161 -0
  17. data/app/components/easy_admin/dashboards/base_card_component.rb +152 -0
  18. data/app/components/easy_admin/dashboards/card_error_component.rb +23 -0
  19. data/app/components/easy_admin/dashboards/card_factory.rb +90 -0
  20. data/app/components/easy_admin/dashboards/card_stream_component.rb +22 -0
  21. data/app/components/easy_admin/dashboards/cards/base_card_component.rb +54 -0
  22. data/app/components/easy_admin/dashboards/cards/chart_card_component.rb +175 -0
  23. data/app/components/easy_admin/dashboards/cards/custom_card_component.rb +50 -0
  24. data/app/components/easy_admin/dashboards/cards/metric_card_component.rb +164 -0
  25. data/app/components/easy_admin/dashboards/cards/table_card_component.rb +148 -0
  26. data/app/components/easy_admin/dashboards/chart_card_component.rb +44 -0
  27. data/app/components/easy_admin/dashboards/metric_card_component.rb +56 -0
  28. data/app/components/easy_admin/dashboards/refresh_stream_component.rb +279 -0
  29. data/app/components/easy_admin/dashboards/show_component.rb +163 -0
  30. data/app/components/easy_admin/dashboards/table_card_component.rb +52 -0
  31. data/app/components/easy_admin/date_picker_component.rb +188 -0
  32. data/app/components/easy_admin/fields/base_component.rb +101 -0
  33. data/app/components/easy_admin/fields/belongs_to_edit_modal_component.rb +117 -0
  34. data/app/components/easy_admin/fields/form/belongs_to_component.rb +82 -0
  35. data/app/components/easy_admin/fields/form/boolean_component.rb +100 -0
  36. data/app/components/easy_admin/fields/form/date_component.rb +55 -0
  37. data/app/components/easy_admin/fields/form/datetime_component.rb +55 -0
  38. data/app/components/easy_admin/fields/form/email_component.rb +55 -0
  39. data/app/components/easy_admin/fields/form/file_component.rb +190 -0
  40. data/app/components/easy_admin/fields/form/has_many_component.rb +416 -0
  41. data/app/components/easy_admin/fields/form/json_component.rb +81 -0
  42. data/app/components/easy_admin/fields/form/number_component.rb +55 -0
  43. data/app/components/easy_admin/fields/form/select_component.rb +326 -0
  44. data/app/components/easy_admin/fields/form/text_component.rb +55 -0
  45. data/app/components/easy_admin/fields/form/textarea_component.rb +54 -0
  46. data/app/components/easy_admin/fields/index/belongs_to_component.rb +93 -0
  47. data/app/components/easy_admin/fields/index/boolean_component.rb +29 -0
  48. data/app/components/easy_admin/fields/index/date_component.rb +13 -0
  49. data/app/components/easy_admin/fields/index/datetime_component.rb +13 -0
  50. data/app/components/easy_admin/fields/index/email_component.rb +24 -0
  51. data/app/components/easy_admin/fields/index/filters/base_component.rb +48 -0
  52. data/app/components/easy_admin/fields/index/filters/boolean_component.rb +96 -0
  53. data/app/components/easy_admin/fields/index/filters/date_component.rb +182 -0
  54. data/app/components/easy_admin/fields/index/filters/number_component.rb +30 -0
  55. data/app/components/easy_admin/fields/index/filters/select_component.rb +101 -0
  56. data/app/components/easy_admin/fields/index/filters/string_component.rb +32 -0
  57. data/app/components/easy_admin/fields/index/json_component.rb +23 -0
  58. data/app/components/easy_admin/fields/index/number_component.rb +20 -0
  59. data/app/components/easy_admin/fields/index/select_component.rb +25 -0
  60. data/app/components/easy_admin/fields/index/text_component.rb +20 -0
  61. data/app/components/easy_admin/fields/inline_edit_modal_component.rb +135 -0
  62. data/app/components/easy_admin/fields/inline_edit_trigger_component.rb +144 -0
  63. data/app/components/easy_admin/fields/show/belongs_to_component.rb +93 -0
  64. data/app/components/easy_admin/fields/show/boolean_component.rb +21 -0
  65. data/app/components/easy_admin/fields/show/date_component.rb +13 -0
  66. data/app/components/easy_admin/fields/show/datetime_component.rb +13 -0
  67. data/app/components/easy_admin/fields/show/email_component.rb +19 -0
  68. data/app/components/easy_admin/fields/show/file_component.rb +304 -0
  69. data/app/components/easy_admin/fields/show/has_many_component.rb +192 -0
  70. data/app/components/easy_admin/fields/show/json_component.rb +45 -0
  71. data/app/components/easy_admin/fields/show/number_component.rb +20 -0
  72. data/app/components/easy_admin/fields/show/select_component.rb +25 -0
  73. data/app/components/easy_admin/fields/show/text_component.rb +17 -0
  74. data/app/components/easy_admin/fields/show/textarea_component.rb +26 -0
  75. data/app/components/easy_admin/filters_component.rb +120 -0
  76. data/app/components/easy_admin/form_tabs_component.rb +166 -0
  77. data/app/components/easy_admin/infinite_scroll_component.rb +82 -0
  78. data/app/components/easy_admin/lazy_chart_card_component.rb +128 -0
  79. data/app/components/easy_admin/lazy_metric_card_component.rb +76 -0
  80. data/app/components/easy_admin/modal_frame_component.rb +26 -0
  81. data/app/components/easy_admin/navbar_component.rb +226 -0
  82. data/app/components/easy_admin/notification_component.rb +83 -0
  83. data/app/components/easy_admin/pagination_component.rb +188 -0
  84. data/app/components/easy_admin/quick_filters_component.rb +65 -0
  85. data/app/components/easy_admin/resource_pagination_component.rb +14 -0
  86. data/app/components/easy_admin/resources/index_component.rb +211 -0
  87. data/app/components/easy_admin/resources/index_frame_component.rb +88 -0
  88. data/app/components/easy_admin/resources/show_page_actions_component.rb +324 -0
  89. data/app/components/easy_admin/resources/table_cell_component.rb +145 -0
  90. data/app/components/easy_admin/resources/table_component.rb +206 -0
  91. data/app/components/easy_admin/resources/table_row_component.rb +160 -0
  92. data/app/components/easy_admin/row_action_form_component.rb +127 -0
  93. data/app/components/easy_admin/scopes_component.rb +224 -0
  94. data/app/components/easy_admin/settings_sidebar_component.rb +140 -0
  95. data/app/components/easy_admin/show_layout_component.rb +600 -0
  96. data/app/components/easy_admin/sidebar_component.rb +174 -0
  97. data/app/components/easy_admin/turbo/response_component.rb +40 -0
  98. data/app/components/easy_admin/turbo/stream_component.rb +28 -0
  99. data/app/controllers/easy_admin/application_controller.rb +66 -0
  100. data/app/controllers/easy_admin/batch_actions_controller.rb +166 -0
  101. data/app/controllers/easy_admin/confirmation_modal_controller.rb +20 -0
  102. data/app/controllers/easy_admin/dashboard_controller.rb +6 -0
  103. data/app/controllers/easy_admin/dashboards_controller.rb +123 -0
  104. data/app/controllers/easy_admin/passwords_controller.rb +15 -0
  105. data/app/controllers/easy_admin/registrations_controller.rb +52 -0
  106. data/app/controllers/easy_admin/resources_controller.rb +907 -0
  107. data/app/controllers/easy_admin/row_actions_controller.rb +216 -0
  108. data/app/controllers/easy_admin/sessions_controller.rb +32 -0
  109. data/app/controllers/easy_admin/settings_controller.rb +94 -0
  110. data/app/helpers/easy_admin/application_helper.rb +4 -0
  111. data/app/helpers/easy_admin/dashboards_helper.rb +121 -0
  112. data/app/helpers/easy_admin/fields_helper.rb +27 -0
  113. data/app/helpers/easy_admin/pagy_helper.rb +30 -0
  114. data/app/helpers/easy_admin/resources_helper.rb +39 -0
  115. data/app/javascript/easy_admin/application.js +12 -0
  116. data/app/javascript/easy_admin/controllers/batch_modal_controller.js +66 -0
  117. data/app/javascript/easy_admin/controllers/batch_selection_controller.js +223 -0
  118. data/app/javascript/easy_admin/controllers/chart_controller.js +216 -0
  119. data/app/javascript/easy_admin/controllers/collapsible_filters_controller.js +118 -0
  120. data/app/javascript/easy_admin/controllers/confirmation_modal_controller.js +64 -0
  121. data/app/javascript/easy_admin/controllers/context_menu_controller.js +227 -0
  122. data/app/javascript/easy_admin/controllers/date_picker_controller.js +309 -0
  123. data/app/javascript/easy_admin/controllers/dropdown_controller.js +63 -0
  124. data/app/javascript/easy_admin/controllers/event_emitter_controller.js +19 -0
  125. data/app/javascript/easy_admin/controllers/file_controller.js +121 -0
  126. data/app/javascript/easy_admin/controllers/form_tabs_controller.js +100 -0
  127. data/app/javascript/easy_admin/controllers/has_many_search_controller.js +76 -0
  128. data/app/javascript/easy_admin/controllers/infinite_scroll_controller.js +174 -0
  129. data/app/javascript/easy_admin/controllers/ios_alert_controller.js +195 -0
  130. data/app/javascript/easy_admin/controllers/jsoneditor_controller.js +88 -0
  131. data/app/javascript/easy_admin/controllers/modal_controller.js +75 -0
  132. data/app/javascript/easy_admin/controllers/navbar_scroll_controller.js +76 -0
  133. data/app/javascript/easy_admin/controllers/notification_controller.js +48 -0
  134. data/app/javascript/easy_admin/controllers/row_action_controller.js +124 -0
  135. data/app/javascript/easy_admin/controllers/row_modal_controller.js +59 -0
  136. data/app/javascript/easy_admin/controllers/select_field_controller.js +618 -0
  137. data/app/javascript/easy_admin/controllers/settings_button_controller.js +8 -0
  138. data/app/javascript/easy_admin/controllers/settings_sidebar_controller.js +186 -0
  139. data/app/javascript/easy_admin/controllers/sidebar_controller.js +102 -0
  140. data/app/javascript/easy_admin/controllers/sidebar_mobile_controller.js +23 -0
  141. data/app/javascript/easy_admin/controllers/sidebar_nav_controller.js +96 -0
  142. data/app/javascript/easy_admin/controllers/table_controller.js +28 -0
  143. data/app/javascript/easy_admin/controllers/table_row_controller.js +16 -0
  144. data/app/javascript/easy_admin/controllers/toggle_switch_controller.js +22 -0
  145. data/app/javascript/easy_admin/controllers/turbo_stream_redirect.js +9 -0
  146. data/app/javascript/easy_admin/controllers.js +54 -0
  147. data/app/javascript/easy_admin.base.js +4 -0
  148. data/app/models/easy_admin/admin_user.rb +53 -0
  149. data/app/models/easy_admin/application_record.rb +5 -0
  150. data/app/views/easy_admin/dashboard/index.html.erb +3 -0
  151. data/app/views/easy_admin/dashboards/show.html.erb +7 -0
  152. data/app/views/easy_admin/passwords/edit.html.erb +42 -0
  153. data/app/views/easy_admin/passwords/new.html.erb +41 -0
  154. data/app/views/easy_admin/registrations/new.html.erb +65 -0
  155. data/app/views/easy_admin/resources/_redirect.turbo_stream.erb +3 -0
  156. data/app/views/easy_admin/resources/_table_rows.html.erb +46 -0
  157. data/app/views/easy_admin/resources/edit.html.erb +151 -0
  158. data/app/views/easy_admin/resources/index.html.erb +12 -0
  159. data/app/views/easy_admin/resources/index.turbo_stream.erb +139 -0
  160. data/app/views/easy_admin/resources/index_frame.html.erb +142 -0
  161. data/app/views/easy_admin/resources/new.html.erb +100 -0
  162. data/app/views/easy_admin/resources/show.html.erb +31 -0
  163. data/app/views/easy_admin/sessions/new.html.erb +55 -0
  164. data/app/views/easy_admin/settings/_form.html.erb +51 -0
  165. data/app/views/easy_admin/settings/index.html.erb +53 -0
  166. data/app/views/layouts/easy_admin/application.html.erb +48 -0
  167. data/app/views/layouts/easy_admin/auth.html.erb +34 -0
  168. data/config/initializers/easy_admin_card_factory.rb +27 -0
  169. data/config/initializers/pagy.rb +15 -0
  170. data/config/initializers/rack_mini_profiler.rb +67 -0
  171. data/config/routes.rb +70 -0
  172. data/db/migrate/20250101000001_create_easy_admin_admin_users.rb +45 -0
  173. data/lib/easy-admin.rb +32 -0
  174. data/lib/easy_admin/action.rb +159 -0
  175. data/lib/easy_admin/batch_action.rb +134 -0
  176. data/lib/easy_admin/configuration.rb +75 -0
  177. data/lib/easy_admin/dashboard.rb +110 -0
  178. data/lib/easy_admin/dashboard_registry.rb +30 -0
  179. data/lib/easy_admin/delete_action.rb +22 -0
  180. data/lib/easy_admin/engine.rb +54 -0
  181. data/lib/easy_admin/field.rb +118 -0
  182. data/lib/easy_admin/resource.rb +806 -0
  183. data/lib/easy_admin/resource_registry.rb +22 -0
  184. data/lib/easy_admin/types/json_type.rb +25 -0
  185. data/lib/easy_admin/version.rb +3 -0
  186. data/lib/generators/easy_admin/auth_generator.rb +69 -0
  187. data/lib/generators/easy_admin/card/card_generator.rb +94 -0
  188. data/lib/generators/easy_admin/card/templates/card_component.rb.erb +127 -0
  189. data/lib/generators/easy_admin/card/templates/card_component_spec.rb.erb +122 -0
  190. data/lib/generators/easy_admin/install/templates/easy_admin.rb +31 -0
  191. data/lib/generators/easy_admin/install_generator.rb +25 -0
  192. data/lib/generators/easy_admin/rbac/rbac_generator.rb +244 -0
  193. data/lib/generators/easy_admin/rbac/templates/add_rbac_to_admin_users.rb +23 -0
  194. data/lib/generators/easy_admin/rbac/templates/super_admin.rb +34 -0
  195. data/lib/generators/easy_admin/resource_generator.rb +43 -0
  196. data/lib/generators/easy_admin/templates/AUTH_README +35 -0
  197. data/lib/generators/easy_admin/templates/README +27 -0
  198. data/lib/generators/easy_admin/templates/create_easy_admin_admin_users.rb +45 -0
  199. data/lib/generators/easy_admin/templates/devise.rb +267 -0
  200. data/lib/generators/easy_admin/templates/easy_admin.rb +24 -0
  201. data/lib/generators/easy_admin/templates/resource.rb +29 -0
  202. data/lib/tasks/easy_admin_tasks.rake +4 -0
  203. metadata +445 -0
@@ -0,0 +1,22 @@
1
+ module EasyAdmin
2
+ class ResourceRegistry
3
+ @@resources = {}
4
+
5
+ def self.register(resource_class)
6
+ route_key = resource_class.name.demodulize.gsub(/Resource$/, '').downcase.pluralize
7
+ @@resources[route_key] = resource_class
8
+ end
9
+
10
+ def self.find_resource(route_key)
11
+ @@resources[route_key.to_s]
12
+ end
13
+
14
+ def self.all_resources
15
+ @@resources
16
+ end
17
+
18
+ def self.clear
19
+ @@resources = {}
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,25 @@
1
+ module EasyAdmin
2
+ module Types
3
+ class JsonType < ActiveRecord::Type::Json
4
+ # Inherit from Rails' native JSON type for better compatibility
5
+ def type
6
+ :json
7
+ end
8
+
9
+ def cast(value)
10
+ case value
11
+ when String
12
+ # Handle JSON strings from form inputs
13
+ begin
14
+ JSON.parse(value)
15
+ rescue JSON::ParserError
16
+ value # Return original string if not valid JSON
17
+ end
18
+ else
19
+ # Let Rails handle other types
20
+ super
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,3 @@
1
+ module EasyAdmin
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,69 @@
1
+ require 'rails/generators'
2
+ require 'rails/generators/migration'
3
+
4
+ module EasyAdmin
5
+ module Generators
6
+ class AuthGenerator < Rails::Generators::Base
7
+ include Rails::Generators::Migration
8
+
9
+ source_root File.expand_path('../templates', __FILE__)
10
+
11
+ desc 'Generate EasyAdmin authentication setup'
12
+
13
+ def self.next_migration_number(path)
14
+ Time.current.utc.strftime("%Y%m%d%H%M%S")
15
+ end
16
+
17
+ def copy_migration
18
+ migration_template(
19
+ 'create_easy_admin_admin_users.rb',
20
+ 'db/migrate/create_easy_admin_admin_users.rb',
21
+ migration_version: migration_version
22
+ )
23
+ end
24
+
25
+ def add_devise_initializer
26
+ copy_file 'devise.rb', 'config/initializers/easy_admin_devise.rb'
27
+ end
28
+
29
+ def add_routes
30
+ route "mount EasyAdmin::Engine => '/admin', as: 'easy_admin'"
31
+ end
32
+
33
+ def create_default_admin
34
+ create_file 'db/seeds/easy_admin.rb', <<~RUBY
35
+ # Create default EasyAdmin admin user
36
+ if Rails.env.development?
37
+ EasyAdmin::AdminUser.find_or_create_by(email: 'admin@example.com') do |admin|
38
+ admin.password = 'password'
39
+ admin.password_confirmation = 'password'
40
+ admin.first_name = 'Admin'
41
+ admin.last_name = 'User'
42
+ admin.confirmed_at = Time.current
43
+ end
44
+
45
+ puts "EasyAdmin default admin user created!"
46
+ puts "Email: admin@example.com"
47
+ puts "Password: password"
48
+ end
49
+ RUBY
50
+
51
+ append_to_file 'db/seeds.rb', <<~RUBY
52
+
53
+ # Load EasyAdmin seeds
54
+ load Rails.root.join('db/seeds/easy_admin.rb')
55
+ RUBY
56
+ end
57
+
58
+ def show_readme
59
+ readme 'AUTH_README'
60
+ end
61
+
62
+ private
63
+
64
+ def migration_version
65
+ "[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,94 @@
1
+ require 'rails/generators'
2
+
3
+ module EasyAdmin
4
+ module Generators
5
+ class CardGenerator < Rails::Generators::NamedBase
6
+ source_root File.expand_path('templates', __dir__)
7
+
8
+ class_option :type, type: :string, default: 'custom',
9
+ desc: 'Type of card component (metric, chart, table, custom)'
10
+
11
+ def create_card_component
12
+ template 'card_component.rb.erb',
13
+ "app/components/#{application_name.underscore}/dashboards/cards/#{file_name}_card_component.rb"
14
+ end
15
+
16
+ def create_spec_file
17
+ return unless defined?(RSpec)
18
+
19
+ template 'card_component_spec.rb.erb',
20
+ "spec/components/#{application_name.underscore}/dashboards/cards/#{file_name}_card_component_spec.rb"
21
+ end
22
+
23
+ def register_card_component
24
+ initializer_path = "config/initializers/easy_admin_card_factory.rb"
25
+
26
+ if File.exist?(initializer_path)
27
+ append_to_file initializer_path, registration_code
28
+ else
29
+ create_file initializer_path, initial_configuration + registration_code
30
+ end
31
+ end
32
+
33
+ def show_usage_example
34
+ say "\nCard component created successfully!"
35
+ say "Usage example in your dashboard:"
36
+ say ""
37
+ say " #{class_name.underscore}_card :#{file_name}, title: \"#{human_name}\""
38
+ say ""
39
+ say "Or as a custom card:"
40
+ say ""
41
+ say " card :#{file_name},"
42
+ say " type: :#{options[:type]},"
43
+ say " title: \"#{human_name}\","
44
+ say " component_class: \"#{component_class_name}\""
45
+ say ""
46
+ end
47
+
48
+ private
49
+
50
+ def application_name
51
+ Rails.application.class.module_parent.name
52
+ end
53
+
54
+ def component_class_name
55
+ "#{application_name}::Dashboards::Cards::#{class_name}CardComponent"
56
+ end
57
+
58
+ def human_name
59
+ name.humanize
60
+ end
61
+
62
+ def card_type
63
+ options[:type]
64
+ end
65
+
66
+ def base_class
67
+ case card_type
68
+ when 'metric'
69
+ 'EasyAdmin::Dashboards::Cards::MetricCardComponent'
70
+ when 'chart'
71
+ 'EasyAdmin::Dashboards::Cards::ChartCardComponent'
72
+ when 'table'
73
+ 'EasyAdmin::Dashboards::Cards::TableCardComponent'
74
+ else
75
+ 'EasyAdmin::Dashboards::Cards::BaseCardComponent'
76
+ end
77
+ end
78
+
79
+ def registration_code
80
+ "\n# Generated card component registration\n" +
81
+ "EasyAdmin::Dashboards::CardFactory.register(:#{file_name}, #{component_class_name})\n"
82
+ end
83
+
84
+ def initial_configuration
85
+ <<~RUBY
86
+ # EasyAdmin Card Factory Configuration
87
+ #
88
+ # This file registers custom card components with the factory.
89
+
90
+ RUBY
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,127 @@
1
+ module <%= application_name %>
2
+ module Dashboards
3
+ module Cards
4
+ class <%= class_name %>CardComponent < <%= base_class %>
5
+ private
6
+
7
+ def render_card_content
8
+ div(class: "flex flex-col h-full") do
9
+ # Card Content
10
+ div(class: "flex-1 p-6") do
11
+ <% case card_type %>
12
+ <% when 'metric' %>
13
+ render_metric_content
14
+ <% when 'chart' %>
15
+ render_chart_content
16
+ <% when 'table' %>
17
+ render_table_content
18
+ <% else %>
19
+ render_custom_content
20
+ <% end %>
21
+ end
22
+ end
23
+ end
24
+
25
+ <% case card_type %>
26
+ <% when 'metric' %>
27
+ def render_metric_content
28
+ # Implement your metric card logic here
29
+ div(class: "text-center") do
30
+ div(class: "text-3xl font-bold text-gray-900 mb-2") do
31
+ card_data[:value] || "N/A"
32
+ end
33
+ if card_data[:description]
34
+ p(class: "text-sm text-gray-600") { card_data[:description] }
35
+ end
36
+ end
37
+ end
38
+
39
+ <% when 'chart' %>
40
+ def render_chart_content
41
+ # Implement your chart card logic here
42
+ if card_data[:chart_data] && card_data[:chart_data].any?
43
+ div(
44
+ class: "ea-chart-container",
45
+ data: {
46
+ controller: "chart",
47
+ chart_type_value: card[:chart_type] || "line",
48
+ chart_data_value: prepare_chart_data.to_json
49
+ },
50
+ style: "height: #{chart_height}px;"
51
+ ) do
52
+ unsafe_raw "<canvas></canvas>"
53
+ end
54
+ else
55
+ render_no_data_message
56
+ end
57
+ end
58
+
59
+ def prepare_chart_data
60
+ # Customize chart data preparation
61
+ {
62
+ labels: card_data[:chart_data]&.map { |d| d[:label] || d[:date] } || [],
63
+ datasets: [{
64
+ data: card_data[:chart_data]&.map { |d| d[:value] } || [],
65
+ backgroundColor: 'rgba(59, 130, 246, 0.2)',
66
+ borderColor: 'rgb(59, 130, 246)'
67
+ }]
68
+ }
69
+ end
70
+
71
+ <% when 'table' %>
72
+ def render_table_content
73
+ # Implement your table card logic here
74
+ if card_data[:rows] && card_data[:rows].any?
75
+ table(class: "min-w-full") do
76
+ if card_data[:headers]
77
+ thead do
78
+ tr do
79
+ card_data[:headers].each do |header|
80
+ th(class: "px-4 py-2 text-left") { header }
81
+ end
82
+ end
83
+ end
84
+ end
85
+ tbody do
86
+ card_data[:rows].each do |row|
87
+ tr do
88
+ row.each do |cell|
89
+ td(class: "px-4 py-2") { cell.to_s }
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
95
+ else
96
+ render_no_data_message
97
+ end
98
+ end
99
+
100
+ <% else %>
101
+ def render_custom_content
102
+ # Implement your custom card logic here
103
+ div(class: "text-center text-gray-500") do
104
+ h4(class: "text-lg font-medium mb-2") { "<%= human_name %>" }
105
+ p { "Implement your custom card content here." }
106
+
107
+ # Display card data for debugging
108
+ if card_data && !card_data.empty?
109
+ div(class: "mt-4 p-4 bg-gray-100 rounded text-xs") do
110
+ pre { card_data.to_json }
111
+ end
112
+ end
113
+ end
114
+ end
115
+
116
+ <% end %>
117
+ <% unless card_type == 'metric' %>
118
+ def render_no_data_message
119
+ div(class: "flex items-center justify-center py-8 text-gray-500") do
120
+ p { "No data available" }
121
+ end
122
+ end
123
+ <% end %>
124
+ end
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,122 @@
1
+ require 'rails_helper'
2
+
3
+ RSpec.describe <%= component_class_name %>, type: :component do
4
+ let(:card) do
5
+ {
6
+ name: :<%= file_name %>,
7
+ type: :<%= card_type %>,
8
+ title: "<%= human_name %>",
9
+ cols: 1,
10
+ rows: 1
11
+ }
12
+ end
13
+
14
+ let(:card_data) { {} }
15
+ let(:dashboard_class) { double('DashboardClass') }
16
+
17
+ let(:component) do
18
+ described_class.new(
19
+ card: card,
20
+ card_data: card_data,
21
+ dashboard_class: dashboard_class
22
+ )
23
+ end
24
+
25
+ describe '#view_template' do
26
+ it 'renders without errors' do
27
+ expect { render_inline(component) }.not_to raise_error
28
+ end
29
+
30
+ it 'includes the card title' do
31
+ render_inline(component)
32
+
33
+ expect(page).to have_content("<%= human_name %>")
34
+ end
35
+
36
+ <% case card_type %>
37
+ <% when 'metric' %>
38
+ context 'with metric data' do
39
+ let(:card_data) do
40
+ {
41
+ value: 1234,
42
+ description: 'Test metric'
43
+ }
44
+ end
45
+
46
+ it 'displays the metric value' do
47
+ render_inline(component)
48
+
49
+ expect(page).to have_content('1234')
50
+ expect(page).to have_content('Test metric')
51
+ end
52
+ end
53
+
54
+ <% when 'chart' %>
55
+ context 'with chart data' do
56
+ let(:card_data) do
57
+ {
58
+ chart_data: [
59
+ { label: 'Jan', value: 100 },
60
+ { label: 'Feb', value: 200 }
61
+ ]
62
+ }
63
+ end
64
+
65
+ it 'renders chart container' do
66
+ render_inline(component)
67
+
68
+ expect(page).to have_css('.ea-chart-container')
69
+ expect(page).to have_css('canvas')
70
+ end
71
+ end
72
+
73
+ context 'without chart data' do
74
+ it 'shows no data message' do
75
+ render_inline(component)
76
+
77
+ expect(page).to have_content('No data available')
78
+ end
79
+ end
80
+
81
+ <% when 'table' %>
82
+ context 'with table data' do
83
+ let(:card_data) do
84
+ {
85
+ headers: ['Name', 'Value'],
86
+ rows: [
87
+ ['Item 1', '100'],
88
+ ['Item 2', '200']
89
+ ]
90
+ }
91
+ end
92
+
93
+ it 'renders table with headers and rows' do
94
+ render_inline(component)
95
+
96
+ expect(page).to have_css('table')
97
+ expect(page).to have_content('Name')
98
+ expect(page).to have_content('Value')
99
+ expect(page).to have_content('Item 1')
100
+ expect(page).to have_content('Item 2')
101
+ end
102
+ end
103
+
104
+ context 'without table data' do
105
+ it 'shows no data message' do
106
+ render_inline(component)
107
+
108
+ expect(page).to have_content('No data available')
109
+ end
110
+ end
111
+
112
+ <% else %>
113
+ it 'displays custom content' do
114
+ render_inline(component)
115
+
116
+ expect(page).to have_content("<%= human_name %>")
117
+ expect(page).to have_content('Implement your custom card content')
118
+ end
119
+
120
+ <% end %>
121
+ end
122
+ end
@@ -0,0 +1,31 @@
1
+ # EasyAdmin Configuration
2
+ EasyAdmin.configure do |config|
3
+ # Application name (shown in sidebar header)
4
+ config.app_name = "My Admin Panel"
5
+
6
+ # Enable performance profiler (rack-mini-profiler)
7
+ # Shows performance metrics in bottom-left corner
8
+ # Recommended: true for development, false for production
9
+ config.enable_profiler = Rails.env.development?
10
+
11
+ # Enable global settings panel (requires Flipper gem)
12
+ # config.global_settings = true
13
+
14
+ # Configure sidebar navigation
15
+ config.sidebar do
16
+ item "Dashboard", "/admin", icon: "🏠", active: true
17
+
18
+ group "Content", icon: "📝" do
19
+ item "Posts", "/admin/posts"
20
+ item "Categories", "/admin/categories"
21
+ item "Comments", "/admin/comments"
22
+ end
23
+
24
+ group "Users", icon: "👥" do
25
+ item "Users", "/admin/users"
26
+ item "Admin Users", "/admin/admin_users"
27
+ end
28
+
29
+ item "Settings", "/admin/settings", icon: "⚙️"
30
+ end
31
+ end
@@ -0,0 +1,25 @@
1
+ module EasyAdmin
2
+ module Generators
3
+ class InstallGenerator < Rails::Generators::Base
4
+ desc "Creates EasyAdmin initializer"
5
+
6
+ def self.source_root
7
+ @source_root ||= File.expand_path("templates", __dir__)
8
+ end
9
+
10
+ def create_initializer
11
+ template "easy_admin.rb", "config/initializers/easy_admin.rb"
12
+ end
13
+
14
+ def show_readme
15
+ readme "README" if behavior == :invoke
16
+ end
17
+
18
+ private
19
+
20
+ def readme(filename)
21
+ say File.read(File.join(self.class.source_root, filename))
22
+ end
23
+ end
24
+ end
25
+ end