solidstats 1.0.0 → 2.0.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 (97) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +85 -0
  3. data/README.md +35 -0
  4. data/app/assets/javascripts/solidstats/application.js +257 -0
  5. data/app/assets/javascripts/solidstats/dashboard.js +225 -0
  6. data/app/assets/javascripts/solidstats/gem_metadata.js +554 -0
  7. data/app/assets/stylesheets/solidstats/application.css +6 -1
  8. data/app/assets/stylesheets/solidstats/components/action_button.css +99 -0
  9. data/app/assets/stylesheets/solidstats/components/dashboard.css +151 -0
  10. data/app/assets/stylesheets/solidstats/components/dashboard_header.css +93 -0
  11. data/app/assets/stylesheets/solidstats/components/dashboard_layout.css +97 -0
  12. data/app/assets/stylesheets/solidstats/components/gem_metadata.css +1403 -0
  13. data/app/assets/stylesheets/solidstats/components/navigation.css +80 -0
  14. data/app/assets/stylesheets/solidstats/components/quick_navigation.css +54 -0
  15. data/app/assets/stylesheets/solidstats/components/security.css +332 -0
  16. data/app/assets/stylesheets/solidstats/components/status_badge.css +58 -0
  17. data/app/assets/stylesheets/solidstats/components/summary_card.css +66 -0
  18. data/app/assets/stylesheets/solidstats/components/tab_navigation.css +95 -0
  19. data/app/components/solidstats/base_component.rb +88 -0
  20. data/app/components/solidstats/code_quality/code_quality_section_component.html.erb +0 -0
  21. data/app/components/solidstats/code_quality/code_quality_section_component.rb +0 -0
  22. data/app/components/solidstats/code_quality/section_component.html.erb +45 -0
  23. data/app/components/solidstats/code_quality/section_component.rb +34 -0
  24. data/app/components/solidstats/dashboard_header_component.html.erb +39 -0
  25. data/app/components/solidstats/dashboard_header_component.rb +33 -0
  26. data/app/components/solidstats/previews/action_button_component_preview/button_vs_link.html.erb +6 -0
  27. data/app/components/solidstats/previews/action_button_component_preview/sizes.html.erb +6 -0
  28. data/app/components/solidstats/previews/action_button_component_preview/variants.html.erb +6 -0
  29. data/app/components/solidstats/previews/action_button_component_preview/with_icons.html.erb +6 -0
  30. data/app/components/solidstats/previews/action_button_component_preview.rb +64 -0
  31. data/app/components/solidstats/previews/navigation_component_preview.rb +74 -0
  32. data/app/components/solidstats/previews/stats_overview_component_preview.rb +100 -0
  33. data/app/components/solidstats/previews/status_badge_component_preview/sizes.html.erb +6 -0
  34. data/app/components/solidstats/previews/status_badge_component_preview/statuses.html.erb +6 -0
  35. data/app/components/solidstats/previews/status_badge_component_preview/with_icons.html.erb +6 -0
  36. data/app/components/solidstats/previews/status_badge_component_preview.rb +49 -0
  37. data/app/components/solidstats/previews/summary_card_component_preview/clickable.html.erb +9 -0
  38. data/app/components/solidstats/previews/summary_card_component_preview/dashboard_layout.html.erb +9 -0
  39. data/app/components/solidstats/previews/summary_card_component_preview/statuses.html.erb +6 -0
  40. data/app/components/solidstats/previews/summary_card_component_preview/value_formats.html.erb +6 -0
  41. data/app/components/solidstats/previews/summary_card_component_preview.rb +67 -0
  42. data/app/components/solidstats/quick_navigation_component.html.erb +8 -0
  43. data/app/components/solidstats/quick_navigation_component.rb +21 -0
  44. data/app/components/solidstats/security/gem_impact_analysis_component.html.erb +44 -0
  45. data/app/components/solidstats/security/gem_impact_analysis_component.rb +45 -0
  46. data/app/components/solidstats/security/overview_component.html.erb +21 -0
  47. data/app/components/solidstats/security/overview_component.rb +104 -0
  48. data/app/components/solidstats/security/section_component.html.erb +26 -0
  49. data/app/components/solidstats/security/section_component.rb +52 -0
  50. data/app/components/solidstats/security/timeline_component.html.erb +39 -0
  51. data/app/components/solidstats/security/timeline_component.rb +43 -0
  52. data/app/components/solidstats/tasks_section_component.html.erb +17 -0
  53. data/app/components/solidstats/tasks_section_component.rb +22 -0
  54. data/app/components/solidstats/ui/action_button_component.html.erb +6 -0
  55. data/app/components/solidstats/ui/action_button_component.rb +71 -0
  56. data/app/components/solidstats/ui/dashboard_layout_component.html.erb +19 -0
  57. data/app/components/solidstats/ui/dashboard_layout_component.rb +85 -0
  58. data/app/components/solidstats/ui/navigation_component.html.erb +34 -0
  59. data/app/components/solidstats/ui/navigation_component.rb +72 -0
  60. data/app/components/solidstats/ui/stats_overview_component.html.erb +14 -0
  61. data/app/components/solidstats/ui/stats_overview_component.rb +78 -0
  62. data/app/components/solidstats/ui/status_badge_component.html.erb +6 -0
  63. data/app/components/solidstats/ui/status_badge_component.rb +42 -0
  64. data/app/components/solidstats/ui/summary_card_component.html.erb +12 -0
  65. data/app/components/solidstats/ui/summary_card_component.rb +63 -0
  66. data/app/components/solidstats/ui/tab_navigation_component.html.erb +22 -0
  67. data/app/components/solidstats/ui/tab_navigation_component.rb +79 -0
  68. data/app/controllers/solidstats/dashboard_controller.rb +22 -0
  69. data/app/controllers/solidstats/gem_metadata_controller.rb +12 -0
  70. data/app/helpers/solidstats/application_helper.rb +42 -0
  71. data/app/services/solidstats/gem_metadata/fetcher_service.rb +136 -0
  72. data/app/services/solidstats/log_size_monitor_service.rb +94 -0
  73. data/app/views/layouts/solidstats/application.html.erb +2 -1
  74. data/app/views/solidstats/dashboard/_log_monitor.html.erb +759 -0
  75. data/app/views/solidstats/dashboard/index.html.erb +67 -1323
  76. data/app/views/solidstats/gem_metadata/_panel.html.erb +419 -0
  77. data/config/routes.rb +7 -0
  78. data/lib/generators/solidstats/feature/feature_generator.rb +170 -0
  79. data/lib/generators/solidstats/feature/templates/component.html.erb +84 -0
  80. data/lib/generators/solidstats/feature/templates/component.rb.erb +103 -0
  81. data/lib/generators/solidstats/feature/templates/component.scss +243 -0
  82. data/lib/generators/solidstats/feature/templates/component_test.rb.erb +183 -0
  83. data/lib/generators/solidstats/feature/templates/controller.rb.erb +44 -0
  84. data/lib/generators/solidstats/feature/templates/controller_test.rb.erb +111 -0
  85. data/lib/generators/solidstats/feature/templates/detail_view.html.erb +755 -0
  86. data/lib/generators/solidstats/feature/templates/preview.rb.erb +107 -0
  87. data/lib/generators/solidstats/feature/templates/service.rb.erb +132 -0
  88. data/lib/generators/solidstats/feature/templates/service_test.rb.erb +109 -0
  89. data/lib/generators/solidstats/install_generator.rb +109 -0
  90. data/lib/generators/solidstats/templates/initializer.rb +112 -0
  91. data/lib/solidstats/asset_compatibility.rb +238 -0
  92. data/lib/solidstats/asset_manifest.rb +205 -0
  93. data/lib/solidstats/engine.rb +114 -9
  94. data/lib/solidstats/version.rb +1 -1
  95. data/lib/solidstats.rb +299 -2
  96. data/lib/tasks/solidstats_install.rake +122 -2
  97. metadata +99 -2
@@ -0,0 +1,238 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solidstats
4
+ # Asset compatibility layer for Rails engines
5
+ # Provides universal asset loading across different Rails asset pipelines
6
+ module AssetCompatibility
7
+ extend self
8
+
9
+ # Include engine assets in host application
10
+ # @param app [Rails::Application] Rails application instance
11
+ def setup_assets(app)
12
+ detect_asset_pipeline(app, force_refresh: true)
13
+ configure_asset_pipeline(app)
14
+ add_asset_helpers(app)
15
+ end
16
+
17
+ # Detect which asset pipeline is being used
18
+ # @param app [Rails::Application] Rails application instance
19
+ # @param force_refresh [Boolean] Force refresh of cached detection
20
+ # @return [Symbol] Detected pipeline (:propshaft, :sprockets, :webpacker, :importmap, :unknown)
21
+ def detect_asset_pipeline(app, force_refresh: false)
22
+ if force_refresh
23
+ @pipeline = nil
24
+ end
25
+
26
+ @pipeline ||= begin
27
+ if propshaft_available?(app)
28
+ :propshaft
29
+ elsif importmap_available?(app)
30
+ :importmap
31
+ elsif webpacker_available?(app)
32
+ :webpacker
33
+ elsif sprockets_available?(app)
34
+ :sprockets
35
+ else
36
+ :unknown
37
+ end
38
+ end
39
+ end
40
+
41
+ # Configure the detected asset pipeline
42
+ # @param app [Rails::Application] Rails application instance
43
+ def configure_asset_pipeline(app)
44
+ case detect_asset_pipeline(app)
45
+ when :propshaft
46
+ configure_propshaft(app)
47
+ when :sprockets
48
+ configure_sprockets(app)
49
+ when :webpacker
50
+ configure_webpacker(app)
51
+ when :importmap
52
+ configure_importmap(app)
53
+ when :unknown
54
+ Solidstats.logger.warn "[Solidstats] No supported asset pipeline detected"
55
+ end
56
+ end
57
+
58
+ # Add universal asset helper methods
59
+ # @param app [Rails::Application] Rails application instance
60
+ def add_asset_helpers(app)
61
+ return unless defined?(ActionView::Base)
62
+
63
+ ActionView::Base.class_eval do
64
+ # Universal stylesheet helper for Solidstats
65
+ def solidstats_stylesheets(*args)
66
+ options = args.extract_options!
67
+ strategy = Solidstats.asset_strategy
68
+
69
+ case strategy
70
+ when :importmap, :sprockets, :propshaft
71
+ stylesheet_link_tag "solidstats/application", **options
72
+ when :webpacker
73
+ if respond_to?(:stylesheet_pack_tag)
74
+ stylesheet_pack_tag "solidstats/application", **options
75
+ else
76
+ stylesheet_link_tag "solidstats/application", **options
77
+ end
78
+ else
79
+ stylesheet_link_tag "solidstats/application", **options
80
+ end
81
+ end
82
+
83
+ # Universal javascript helper for Solidstats
84
+ def solidstats_javascripts(*args)
85
+ options = args.extract_options!
86
+ strategy = Solidstats.asset_strategy
87
+
88
+ case strategy
89
+ when :importmap
90
+ javascript_importmap_tags
91
+ javascript_include_tag "solidstats", **options
92
+ when :webpacker
93
+ if respond_to?(:javascript_pack_tag)
94
+ javascript_pack_tag "solidstats/application", **options
95
+ else
96
+ javascript_include_tag "solidstats/application", **options
97
+ end
98
+ when :sprockets, :propshaft
99
+ javascript_include_tag "solidstats/application", **options
100
+ else
101
+ javascript_include_tag "solidstats/application", **options
102
+ end
103
+ end
104
+
105
+ # Convenience method to include all Solidstats assets
106
+ def solidstats_assets(*args)
107
+ options = args.extract_options!
108
+
109
+ content = []
110
+ content << solidstats_stylesheets(**options.slice(:media, :crossorigin))
111
+ content << solidstats_javascripts(**options.slice(:defer, :async, :crossorigin))
112
+
113
+ safe_join(content, "\n")
114
+ end
115
+ end
116
+
117
+ Solidstats.logger.info "[Solidstats] Added universal asset helpers"
118
+ rescue => e
119
+ Solidstats.logger.warn "[Solidstats] Could not add asset helpers: #{e.message}"
120
+ end
121
+
122
+ private
123
+
124
+ # Check if Propshaft is available
125
+ def propshaft_available?(app)
126
+ defined?(Propshaft) && app.config.respond_to?(:assets) &&
127
+ app.assets.is_a?(Propshaft::Assembly)
128
+ end
129
+
130
+ # Check if Importmap is available
131
+ def importmap_available?(app)
132
+ defined?(Importmap) &&
133
+ app.config.respond_to?(:importmap) &&
134
+ File.exist?(Rails.root.join("config/importmap.rb"))
135
+ end
136
+
137
+ # Check if Webpacker is available
138
+ def webpacker_available?(app)
139
+ defined?(Webpacker) &&
140
+ app.config.respond_to?(:webpacker) &&
141
+ File.exist?(Rails.root.join("config/webpacker.yml"))
142
+ end
143
+
144
+ # Check if Sprockets is available
145
+ def sprockets_available?(app)
146
+ defined?(Sprockets) && app.config.respond_to?(:assets) &&
147
+ !propshaft_available?(app)
148
+ end
149
+
150
+ # Configure Propshaft asset pipeline
151
+ def configure_propshaft(app)
152
+ return unless app.config.respond_to?(:assets)
153
+
154
+ # Add engine asset paths
155
+ engine_paths = [
156
+ Solidstats::Engine.root.join("app", "assets", "stylesheets"),
157
+ Solidstats::Engine.root.join("app", "assets", "javascripts"),
158
+ Solidstats::Engine.root.join("app", "assets", "images")
159
+ ]
160
+
161
+ engine_paths.each do |path|
162
+ path_str = path.to_s
163
+ unless app.config.assets.paths.include?(path_str)
164
+ app.config.assets.paths << path_str
165
+ end
166
+ end
167
+
168
+ # Add to precompile list
169
+ precompile_assets = [
170
+ "solidstats/application.css",
171
+ "solidstats/application.js"
172
+ ]
173
+
174
+ precompile_assets.each do |asset|
175
+ unless app.config.assets.precompile.include?(asset)
176
+ app.config.assets.precompile << asset
177
+ end
178
+ end
179
+
180
+ Solidstats.logger.info "[Solidstats] Configured Propshaft asset pipeline"
181
+ end
182
+
183
+ # Configure Sprockets asset pipeline
184
+ def configure_sprockets(app)
185
+ return unless app.config.respond_to?(:assets)
186
+
187
+ # Add engine asset paths
188
+ engine_paths = [
189
+ Solidstats::Engine.root.join("app", "assets", "stylesheets"),
190
+ Solidstats::Engine.root.join("app", "assets", "javascripts"),
191
+ Solidstats::Engine.root.join("app", "assets", "images")
192
+ ]
193
+
194
+ engine_paths.each do |path|
195
+ path_str = path.to_s
196
+ unless app.config.assets.paths.include?(path_str)
197
+ app.config.assets.paths << path_str
198
+ end
199
+ end
200
+
201
+ # Add to precompile list
202
+ precompile_assets = [
203
+ "solidstats/application.css",
204
+ "solidstats/application.js"
205
+ ]
206
+
207
+ precompile_assets.each do |asset|
208
+ unless app.config.assets.precompile.include?(asset)
209
+ app.config.assets.precompile << asset
210
+ end
211
+ end
212
+
213
+ Solidstats.logger.info "[Solidstats] Configured Sprockets asset pipeline"
214
+ end
215
+
216
+ # Configure Webpacker asset pipeline
217
+ def configure_webpacker(app)
218
+ # Webpacker configuration is more complex and typically requires
219
+ # manual setup in the host application
220
+ Solidstats.logger.info "[Solidstats] Webpacker detected - manual configuration may be required"
221
+
222
+ # Add source path if possible
223
+ if app.config.webpacker.respond_to?(:source_path)
224
+ engine_source = Solidstats::Engine.root.join("app", "javascript")
225
+ if engine_source.exist?
226
+ Solidstats.logger.info "[Solidstats] Engine JavaScript available at: #{engine_source}"
227
+ end
228
+ end
229
+ end
230
+
231
+ # Configure Importmap asset pipeline
232
+ def configure_importmap(app)
233
+ # Importmap configuration is handled through config/importmap.rb
234
+ # The generator should add the appropriate pin statements
235
+ Solidstats.logger.info "[Solidstats] Importmap detected - configuration in config/importmap.rb"
236
+ end
237
+ end
238
+ end
@@ -0,0 +1,205 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Solidstats Asset Manifest
4
+ # This file defines all assets that should be precompiled for production deployment
5
+ # Compatible with Sprockets, Webpacker, and Importmap
6
+
7
+ module Solidstats
8
+ class AssetManifest
9
+ # Define all assets that should be precompiled
10
+ PRECOMPILE_ASSETS = [
11
+ # Main application assets
12
+ "solidstats/application.css",
13
+ "solidstats/application.js",
14
+
15
+ # Component-specific CSS files (using actual filenames)
16
+ "solidstats/components/summary_card.css",
17
+ "solidstats/components/dashboard_layout.css",
18
+ "solidstats/components/tab_navigation.css",
19
+ "solidstats/components/quick_navigation.css",
20
+ "solidstats/components/action_button.css",
21
+ "solidstats/components/dashboard_header.css",
22
+ "solidstats/components/navigation.css",
23
+ "solidstats/components/security.css",
24
+ "solidstats/components/status_badge.css",
25
+ "solidstats/components/dashboard.css"
26
+ ].freeze
27
+
28
+ # Assets that should be included in development mode
29
+ DEVELOPMENT_ASSETS = [
30
+ # Preview and development-only assets
31
+ "solidstats/component_preview.css",
32
+ "solidstats/development_toolbar.css"
33
+ ].freeze
34
+
35
+ # Image assets to precompile
36
+ IMAGE_ASSETS = [
37
+ # Add image assets here when they exist
38
+ # "solidstats/icons/*.png",
39
+ # "solidstats/logos/*.svg"
40
+ ].freeze
41
+
42
+ class << self
43
+ # Get all assets for precompilation based on environment
44
+ # @param environment [String] Rails environment
45
+ # @return [Array<String>] Assets to precompile
46
+ def assets_for_environment(environment = Rails.env)
47
+ assets = PRECOMPILE_ASSETS.dup
48
+
49
+ if environment == "development"
50
+ assets.concat(DEVELOPMENT_ASSETS)
51
+ end
52
+
53
+ assets.concat(IMAGE_ASSETS)
54
+ assets.uniq
55
+ end
56
+
57
+ # Configure asset precompilation for a Rails application
58
+ # @param app [Rails::Application] Rails application instance
59
+ def configure_precompilation(app)
60
+ return unless app.config.respond_to?(:assets)
61
+
62
+ assets_to_add = assets_for_environment - app.config.assets.precompile
63
+
64
+ assets_to_add.each do |asset|
65
+ app.config.assets.precompile << asset
66
+ end
67
+
68
+ # Add asset paths if not already present
69
+ add_asset_paths(app)
70
+
71
+ Rails.logger.info "[Solidstats] Added #{assets_to_add.size} assets to precompilation list"
72
+ end
73
+
74
+ # Add engine asset paths to application
75
+ # @param app [Rails::Application] Rails application instance
76
+ def add_asset_paths(app)
77
+ return unless app.config.respond_to?(:assets)
78
+
79
+ engine_paths = [
80
+ Solidstats::Engine.root.join("app", "assets", "stylesheets"),
81
+ Solidstats::Engine.root.join("app", "assets", "javascripts"),
82
+ Solidstats::Engine.root.join("app", "assets", "images")
83
+ ]
84
+
85
+ engine_paths.each do |path|
86
+ path_str = path.to_s
87
+ unless app.config.assets.paths.include?(path_str)
88
+ app.config.assets.paths << path_str
89
+ end
90
+ end
91
+ end
92
+
93
+ # Get asset fingerprinting configuration
94
+ # @param environment [String] Rails environment
95
+ # @return [Hash] Fingerprinting configuration
96
+ def fingerprint_config(environment = Rails.env)
97
+ case environment
98
+ when "production"
99
+ {
100
+ digest: true,
101
+ compile: false,
102
+ compress: true,
103
+ gzip: true
104
+ }
105
+ when "staging"
106
+ {
107
+ digest: true,
108
+ compile: false,
109
+ compress: true,
110
+ gzip: false
111
+ }
112
+ when "development"
113
+ {
114
+ digest: false,
115
+ compile: true,
116
+ compress: false,
117
+ gzip: false,
118
+ debug: true
119
+ }
120
+ when "test"
121
+ {
122
+ digest: false,
123
+ compile: true,
124
+ compress: false,
125
+ gzip: false,
126
+ debug: false
127
+ }
128
+ else
129
+ # Default safe configuration
130
+ {
131
+ digest: true,
132
+ compile: false,
133
+ compress: true,
134
+ gzip: false
135
+ }
136
+ end
137
+ end
138
+
139
+ # Apply fingerprinting configuration to application
140
+ # @param app [Rails::Application] Rails application instance
141
+ # @param environment [String] Rails environment
142
+ def configure_fingerprinting(app, environment = Rails.env)
143
+ return unless app.config.respond_to?(:assets)
144
+
145
+ config = fingerprint_config(environment)
146
+
147
+ config.each do |key, value|
148
+ if app.config.assets.respond_to?("#{key}=")
149
+ app.config.assets.public_send("#{key}=", value)
150
+ end
151
+ end
152
+
153
+ Rails.logger.info "[Solidstats] Applied #{environment} asset fingerprinting configuration"
154
+ end
155
+
156
+ # Check if all required assets exist
157
+ # @return [Array<String>] Missing assets
158
+ def missing_assets
159
+ missing = []
160
+
161
+ PRECOMPILE_ASSETS.each do |asset|
162
+ asset_path = resolve_asset_path(asset)
163
+ unless File.exist?(asset_path)
164
+ missing << asset
165
+ end
166
+ end
167
+
168
+ missing
169
+ end
170
+
171
+ # Validate that all assets are available
172
+ # @raise [Solidstats::Error] If required assets are missing
173
+ def validate_assets!
174
+ missing = missing_assets
175
+
176
+ unless missing.empty?
177
+ raise Solidstats::Error,
178
+ "Missing required assets: #{missing.join(', ')}"
179
+ end
180
+
181
+ true
182
+ end
183
+
184
+ private
185
+
186
+ # Resolve the file system path for an asset
187
+ # @param asset [String] Asset logical path
188
+ # @return [String] File system path
189
+ def resolve_asset_path(asset)
190
+ # Remove the 'solidstats/' prefix and find the actual file
191
+ relative_path = asset.sub(/^solidstats\//, "")
192
+
193
+ # Try different possible locations
194
+ possible_paths = [
195
+ Solidstats::Engine.root.join("app", "assets", "stylesheets", "solidstats", relative_path),
196
+ Solidstats::Engine.root.join("app", "assets", "javascripts", "solidstats", relative_path),
197
+ Solidstats::Engine.root.join("app", "assets", "images", "solidstats", relative_path)
198
+ ]
199
+
200
+ possible_paths.find { |path| File.exist?(path) } ||
201
+ Solidstats::Engine.root.join("app", "assets", "stylesheets", asset).to_s
202
+ end
203
+ end
204
+ end
205
+ end
@@ -1,22 +1,127 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/engine" if defined?(Rails)
4
+
1
5
  module Solidstats
2
6
  class Engine < ::Rails::Engine
3
- isolate_namespace Solidstats
7
+ isolate_namespace Solidstats if defined?(Rails)
8
+
9
+ # Engine configuration
10
+ config.solidstats = ActiveSupport::OrderedOptions.new
11
+
12
+ # Set default configuration values
13
+ config.before_configuration do
14
+ config.solidstats.cache_duration = 1.hour
15
+ config.solidstats.enable_components = true
16
+ config.solidstats.log_level = :info
17
+ config.solidstats.enable_previews = Rails.env.development?
18
+ end
4
19
 
5
- initializer "solidstats.only_in_dev" do
20
+ # Ensure gem only runs in development environment
21
+ initializer "solidstats.environment_check", before: :load_config_initializers do
6
22
  unless Rails.env.development?
7
- raise "Solidstats can only be used in development mode."
23
+ raise Solidstats::ConfigurationError,
24
+ "Solidstats can only be used in development mode. Current environment: #{Rails.env}"
8
25
  end
9
26
  end
10
27
 
11
- initializer "solidstats.assets.precompile" do |app|
12
- if Rails.env.development?
13
- app.config.assets.precompile += %w[ solidstats/application.css ]
14
- end
28
+ # Load and configure ViewComponent if available
29
+ initializer "solidstats.setup_view_component", after: :load_config_initializers do |app|
30
+ setup_view_component(app) if view_component_available?
31
+ end
32
+
33
+ # Add custom paths for autoloading
34
+ initializer "solidstats.autoload_paths" do |app|
35
+ app.config.autoload_paths += Dir[Engine.root.join("app", "components", "**")]
36
+ app.config.autoload_paths += Dir[Engine.root.join("app", "services", "**")]
15
37
  end
16
38
 
17
- # Load the solidstats rake tasks
39
+ # Load custom rake tasks
18
40
  rake_tasks do
19
- Dir[File.join(File.dirname(__FILE__), "../tasks/**/*.rake")].each { |f| load f }
41
+ load_rake_tasks
42
+ end
43
+
44
+ # Add custom generators path
45
+ config.generators do |g|
46
+ g.test_framework :minitest, spec: false, fixture: false
47
+ end
48
+
49
+ private
50
+
51
+ # Check if ViewComponent is available and properly loaded
52
+ # @return [Boolean] true if ViewComponent is available
53
+ def view_component_available?
54
+ defined?(ViewComponent::Base) && Solidstats.view_component_available?
55
+ end
56
+
57
+ # Configure ViewComponent integration
58
+ # @param app [Rails::Application] Rails application instance
59
+ def setup_view_component(app)
60
+ log_info "🔍 Solidstats: Setting up ViewComponent integration..."
61
+
62
+ begin
63
+ version = ViewComponent::VERSION rescue "unknown"
64
+ log_info "✅ ViewComponent #{version} detected and configured"
65
+
66
+ configure_view_component_settings(app)
67
+ setup_preview_paths(app)
68
+
69
+ log_info "🎯 ViewComponent::Base: #{ViewComponent::Base}"
70
+ rescue StandardError => e
71
+ log_error "❌ ViewComponent setup failed: #{e.message}"
72
+ raise Solidstats::ComponentError, "Failed to configure ViewComponent: #{e.message}"
73
+ end
74
+ end
75
+
76
+ # Configure ViewComponent specific settings
77
+ # @param app [Rails::Application] Rails application instance
78
+ def configure_view_component_settings(app)
79
+ return unless app.config.respond_to?(:view_component)
80
+
81
+ view_component_config = app.config.view_component
82
+ view_component_config.show_previews = config.solidstats.enable_previews
83
+ view_component_config.default_preview_layout = "solidstats/component_preview"
84
+
85
+ # Set preview controller if not already set
86
+ unless view_component_config.preview_controller
87
+ view_component_config.preview_controller = "Solidstats::ComponentPreviewsController"
88
+ end
89
+ end
90
+
91
+ # Setup preview paths for component development
92
+ # @param app [Rails::Application] Rails application instance
93
+ def setup_preview_paths(app)
94
+ return unless app.config.respond_to?(:view_component) && config.solidstats.enable_previews
95
+
96
+ preview_path = Engine.root.join("app", "components", "solidstats", "previews")
97
+
98
+ unless app.config.view_component.preview_paths.include?(preview_path)
99
+ app.config.view_component.preview_paths << preview_path
100
+ log_info "📁 Added preview path: #{preview_path}"
101
+ end
102
+ end
103
+
104
+ # Load custom rake tasks
105
+ def load_rake_tasks
106
+ task_files = Dir[Engine.root.join("lib", "tasks", "**", "*.rake")]
107
+ task_files.each { |file| load file }
108
+
109
+ log_info "📋 Loaded #{task_files.size} rake task(s)" if task_files.any?
110
+ rescue StandardError => e
111
+ log_error "Failed to load rake tasks: #{e.message}"
112
+ end
113
+
114
+ # Logging helpers with consistent formatting
115
+ def log_info(message)
116
+ Rails.logger&.info("[Solidstats] #{message}")
117
+ end
118
+
119
+ def log_error(message)
120
+ Rails.logger&.error("[Solidstats] #{message}")
121
+ end
122
+
123
+ def log_debug(message)
124
+ Rails.logger&.debug("[Solidstats] #{message}")
20
125
  end
21
126
  end
22
127
  end
@@ -1,3 +1,3 @@
1
1
  module Solidstats
2
- VERSION = "1.0.0"
2
+ VERSION = "2.0.0"
3
3
  end