panda-cms 0.8.0 → 0.10.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 (93) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +83 -4
  3. data/app/components/panda/cms/code_component.rb +117 -39
  4. data/app/components/panda/cms/grid_component.rb +26 -6
  5. data/app/components/panda/cms/menu_component.rb +66 -34
  6. data/app/components/panda/cms/page_menu_component.rb +94 -13
  7. data/app/components/panda/cms/rich_text_component.rb +198 -140
  8. data/app/components/panda/cms/text_component.rb +77 -44
  9. data/app/controllers/panda/cms/admin/base_controller.rb +19 -3
  10. data/app/controllers/panda/cms/admin/dashboard_controller.rb +3 -3
  11. data/app/controllers/panda/cms/admin/files_controller.rb +7 -0
  12. data/app/controllers/panda/cms/admin/menus_controller.rb +47 -3
  13. data/app/controllers/panda/cms/admin/pages_controller.rb +6 -1
  14. data/app/controllers/panda/cms/pages_controller.rb +2 -2
  15. data/app/helpers/panda/cms/application_helper.rb +15 -1
  16. data/app/helpers/panda/cms/asset_helper.rb +14 -3
  17. data/app/javascript/panda/cms/application_panda_cms.js +1 -1
  18. data/app/javascript/panda/cms/controllers/code_editor_controller.js +95 -0
  19. data/app/javascript/panda/cms/controllers/file_gallery_controller.js +128 -0
  20. data/app/javascript/panda/cms/controllers/index.js +48 -13
  21. data/app/javascript/panda/cms/controllers/inline_code_editor_controller.js +96 -0
  22. data/app/javascript/panda/cms/controllers/menu_form_controller.js +40 -0
  23. data/app/javascript/panda/cms/controllers/nested_form_controller.js +35 -0
  24. data/app/javascript/panda/cms/controllers/tree_controller.js +214 -0
  25. data/app/javascript/panda/cms/stimulus-loading.js +5 -7
  26. data/app/models/panda/cms/block_content.rb +9 -0
  27. data/app/models/panda/cms/page.rb +41 -0
  28. data/app/models/panda/cms/post.rb +1 -0
  29. data/app/views/panda/cms/admin/dashboard/show.html.erb +5 -5
  30. data/app/views/panda/cms/admin/files/_file_details.html.erb +45 -0
  31. data/app/views/panda/cms/admin/files/index.html.erb +11 -118
  32. data/app/views/panda/cms/admin/forms/index.html.erb +2 -2
  33. data/app/views/panda/cms/admin/forms/new.html.erb +1 -2
  34. data/app/views/panda/cms/admin/forms/show.html.erb +15 -30
  35. data/app/views/panda/cms/admin/menus/_menu_item_fields.html.erb +11 -0
  36. data/app/views/panda/cms/admin/menus/edit.html.erb +64 -0
  37. data/app/views/panda/cms/admin/menus/index.html.erb +3 -2
  38. data/app/views/panda/cms/admin/menus/new.html.erb +40 -0
  39. data/app/views/panda/cms/admin/pages/edit.html.erb +15 -9
  40. data/app/views/panda/cms/admin/pages/index.html.erb +49 -11
  41. data/app/views/panda/cms/admin/pages/new.html.erb +3 -11
  42. data/app/views/panda/cms/admin/posts/_form.html.erb +4 -14
  43. data/app/views/panda/cms/admin/posts/edit.html.erb +2 -2
  44. data/app/views/panda/cms/admin/posts/index.html.erb +3 -3
  45. data/app/views/panda/cms/admin/posts/new.html.erb +1 -1
  46. data/app/views/panda/cms/admin/settings/bulk_editor/new.html.erb +1 -1
  47. data/app/views/panda/cms/admin/settings/index.html.erb +3 -3
  48. data/config/importmap.rb +4 -6
  49. data/config/initializers/panda/cms/healthcheck_log_silencer.rb.disabled +31 -0
  50. data/config/initializers/panda/cms.rb +52 -10
  51. data/config/routes.rb +4 -2
  52. data/db/migrate/20240305000000_convert_html_content_to_editor_js.rb +9 -2
  53. data/db/migrate/20240315125421_add_nested_sets_to_panda_cms_pages.rb +6 -1
  54. data/db/migrate/20250809231125_migrate_users_to_panda_core.rb +23 -21
  55. data/db/migrate/20251104150640_add_cached_last_updated_at_to_panda_cms_pages.rb +22 -0
  56. data/db/migrate/20251104172242_add_page_type_to_panda_cms_pages.rb +6 -0
  57. data/db/migrate/20251104172638_set_page_types_for_existing_pages.rb +27 -0
  58. data/db/migrate/20251105000001_add_pending_review_status_to_pages_and_posts.panda_cms.rb +21 -0
  59. data/lib/generators/panda/cms/install_generator.rb +2 -5
  60. data/lib/panda/cms/asset_loader.rb +36 -16
  61. data/lib/panda/cms/debug.rb +29 -0
  62. data/lib/panda/cms/engine.rb +107 -48
  63. data/lib/panda/cms/features.rb +52 -0
  64. data/lib/panda-cms/version.rb +1 -1
  65. data/lib/panda-cms.rb +5 -6
  66. data/lib/tasks/assets.rake +5 -52
  67. data/lib/tasks/panda_cms_tasks.rake +16 -0
  68. metadata +22 -29
  69. data/app/components/panda/cms/admin/container_component.html.erb +0 -13
  70. data/app/components/panda/cms/admin/flash_message_component.html.erb +0 -31
  71. data/app/components/panda/cms/admin/panel_component.html.erb +0 -7
  72. data/app/components/panda/cms/admin/slideover_component.html.erb +0 -9
  73. data/app/components/panda/cms/admin/slideover_component.rb +0 -15
  74. data/app/components/panda/cms/admin/statistics_component.html.erb +0 -4
  75. data/app/components/panda/cms/admin/statistics_component.rb +0 -16
  76. data/app/components/panda/cms/admin/tab_bar_component.html.erb +0 -35
  77. data/app/components/panda/cms/admin/tab_bar_component.rb +0 -15
  78. data/app/components/panda/cms/admin/table_component.html.erb +0 -29
  79. data/app/components/panda/cms/admin/user_activity_component.html.erb +0 -7
  80. data/app/components/panda/cms/admin/user_activity_component.rb +0 -20
  81. data/app/components/panda/cms/admin/user_display_component.html.erb +0 -17
  82. data/app/components/panda/cms/admin/user_display_component.rb +0 -21
  83. data/app/components/panda/cms/grid_component.html.erb +0 -6
  84. data/app/components/panda/cms/menu_component.html.erb +0 -6
  85. data/app/components/panda/cms/page_menu_component.html.erb +0 -21
  86. data/app/components/panda/cms/rich_text_component.html.erb +0 -90
  87. data/app/views/layouts/panda/cms/application.html.erb +0 -42
  88. data/app/views/panda/cms/admin/shared/_breadcrumbs.html.erb +0 -28
  89. data/app/views/panda/cms/admin/shared/_flash.html.erb +0 -5
  90. data/app/views/panda/cms/admin/shared/_sidebar.html.erb +0 -41
  91. data/app/views/panda/cms/shared/_footer.html.erb +0 -2
  92. data/app/views/panda/cms/shared/_header.html.erb +0 -25
  93. data/config/initializers/panda/cms/healthcheck_log_silencer.rb +0 -13
@@ -0,0 +1,27 @@
1
+ class SetPageTypesForExistingPages < ActiveRecord::Migration[8.0]
2
+ def up
3
+ # Set system type for error pages
4
+ execute <<-SQL
5
+ UPDATE panda_cms_pages
6
+ SET page_type = 'system'
7
+ WHERE path IN ('/404', '/500')
8
+ SQL
9
+
10
+ # Set posts type for news/blog pages
11
+ execute <<-SQL
12
+ UPDATE panda_cms_pages
13
+ SET page_type = 'posts'
14
+ WHERE path LIKE '%news%' OR path LIKE '%blog%' OR path LIKE '%updates%'
15
+ SQL
16
+
17
+ # All other pages remain as 'standard' (the default)
18
+ end
19
+
20
+ def down
21
+ # Reset all to standard
22
+ execute <<-SQL
23
+ UPDATE panda_cms_pages
24
+ SET page_type = 'standard'
25
+ SQL
26
+ end
27
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddPendingReviewStatusToPagesAndPosts < ActiveRecord::Migration[8.0]
4
+ def up
5
+ # Add pending_review status to pages and posts for content approval workflow
6
+ # This allows content creators to submit drafts for editorial review
7
+
8
+ # Note: We're not modifying the enum directly in the database
9
+ # Rails enums are string-based, so we just document the new allowed value
10
+ # The application code will handle the new status value
11
+
12
+ # Update any existing pages/posts that might benefit from this status
13
+ # (In a real migration, you'd add logic here if needed)
14
+ end
15
+
16
+ def down
17
+ # Convert any pending_review items back to draft
18
+ Panda::CMS::Page.where(status: "pending_review").update_all(status: "draft")
19
+ Panda::CMS::Post.where(status: "pending_review").update_all(status: "draft")
20
+ end
21
+ end
@@ -10,11 +10,8 @@ module Generators
10
10
  desc "Adds the basic configuration for Panda CMS to your Rails app."
11
11
 
12
12
  def create_initializer_file
13
- # Add the initializer
14
- initializer_path = "config/initializers/panda/cms.rb"
15
- unless File.exist?("#{::Rails.root}/#{initializer_path}")
16
- FileUtils.cp "#{::Panda::CMS::Engine.root}/#{initializer_path}", "#{::Rails.root}/#{initializer_path}"
17
- end
13
+ # Skip creating initializer - Panda::Core already creates config/initializers/panda.rb
14
+ # See config/initializers/panda/cms.rb in the gem for an example configuration
18
15
 
19
16
  # Add the seed loader to the seeds.rb file
20
17
  unless File.read("#{::Rails.root}/db/seeds.rb")&.include?("Panda::CMS::Engine.load_seed")
@@ -161,19 +161,24 @@ module Panda
161
161
  end
162
162
 
163
163
  def development_javascript_url
164
- # Try cached assets first, then importmap
165
- version = asset_version
166
- # Try root level first (standalone bundle), then versioned directory
167
- root_path = "/panda-cms-assets/panda-cms-#{version}.js"
168
- versioned_path = "/panda-cms-assets/#{version}/panda-cms-#{version}.js"
169
-
170
- if cached_asset_exists?(root_path)
171
- root_path
172
- elsif cached_asset_exists?(versioned_path)
173
- versioned_path
164
+ # In development, use importmap for live-reloading
165
+ # Only use compiled assets in test/CI environments
166
+ if Rails.env.development?
167
+ "/panda/cms/application_panda_cms.js"
174
168
  else
175
- # Fallback to importmap or engine asset
176
- "/assets/panda/cms/controllers/index.js"
169
+ # Try cached assets for test environment
170
+ version = asset_version
171
+ root_path = "/panda-cms-assets/panda-cms-#{version}.js"
172
+ versioned_path = "/panda-cms-assets/#{version}/panda-cms-#{version}.js"
173
+
174
+ if cached_asset_exists?(root_path)
175
+ root_path
176
+ elsif cached_asset_exists?(versioned_path)
177
+ versioned_path
178
+ else
179
+ # Fallback to importmap
180
+ "/panda/cms/application_panda_cms.js"
181
+ end
177
182
  end
178
183
  end
179
184
 
@@ -251,7 +256,7 @@ module Panda
251
256
 
252
257
  def engine_assets_available?
253
258
  # Check if engine's JavaScript files are available
254
- engine_js_path = Rails.root.join("..", "..", "app", "javascript", "panda", "cms", "controllers", "index.js")
259
+ engine_js_path = Panda::CMS::Engine.root.join("app", "javascript", "panda", "cms", "controllers", "index.js")
255
260
  File.exist?(engine_js_path)
256
261
  end
257
262
 
@@ -312,6 +317,21 @@ module Panda
312
317
  end
313
318
  end
314
319
 
320
+ # Simple response object for HTTP requests
321
+ class Response
322
+ attr_reader :code, :body
323
+
324
+ def initialize(success:, code:, body:)
325
+ @success = success
326
+ @code = code
327
+ @body = body
328
+ end
329
+
330
+ def success?
331
+ @success
332
+ end
333
+ end
334
+
315
335
  def fetch_url(url)
316
336
  uri = URI(url)
317
337
  http = Net::HTTP.new(uri.host, uri.port)
@@ -324,14 +344,14 @@ module Panda
324
344
 
325
345
  response = http.request(request)
326
346
 
327
- OpenStruct.new(
328
- success?: response.code.to_i == 200,
347
+ Response.new(
348
+ success: response.code.to_i == 200,
329
349
  code: response.code,
330
350
  body: response.body
331
351
  )
332
352
  rescue => e
333
353
  Rails.logger.error "[Panda CMS] Network error: #{e.message}"
334
- OpenStruct.new(success?: false, code: "error", body: nil)
354
+ Response.new(success: false, code: "error", body: nil)
335
355
  end
336
356
 
337
357
  def asset_integrity(version, filename)
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Panda
4
+ module CMS
5
+ module Debug
6
+ class << self
7
+ # Check if debug mode is enabled via PANDA_DEBUG environment variable
8
+ def enabled?
9
+ ENV["PANDA_DEBUG"].to_s.downcase == "true" || ENV["PANDA_DEBUG"] == "1"
10
+ end
11
+
12
+ # Log a debug message if debug mode is enabled
13
+ def log(message)
14
+ Panda::Core::Debug.log(message, prefix: "PANDA CMS")
15
+ end
16
+
17
+ # Log an object with pretty printing (using awesome_print if available)
18
+ def inspect(object, label: nil)
19
+ Panda::Core::Debug.inspect(object, label: label, prefix: "PANDA CMS")
20
+ end
21
+
22
+ # Enable HTTP debugging for Net::HTTP requests (delegates to Core)
23
+ def enable_http_debug!
24
+ Panda::Core::Debug.enable_http_debug!
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -19,14 +19,8 @@ module Panda
19
19
  #{root}/app/services
20
20
  ]
21
21
 
22
- # Basic session setup only
23
- initializer "panda.cms.session", before: :load_config_initializers do |app|
24
- app.config.middleware = app.config.middleware.dup if app.config.middleware.frozen?
25
-
26
- app.config.session_store :cookie_store, key: "_panda_cms_session"
27
- app.config.middleware.use ActionDispatch::Cookies
28
- app.config.middleware.use ActionDispatch::Session::CookieStore, app.config.session_options
29
- end
22
+ # Session configuration is left to the consuming application
23
+ # The CMS engine does not impose session store requirements
30
24
 
31
25
  config.to_prepare do
32
26
  ApplicationController.helper(::ApplicationHelper)
@@ -43,11 +37,19 @@ module Panda
43
37
  end
44
38
 
45
39
  # Make files in public available to the main app (e.g. /panda_cms-assets/favicon.ico)
46
- config.app_middleware.use(
47
- Rack::Static,
40
+ config.middleware.use Rack::Static,
48
41
  urls: ["/panda-cms-assets"],
49
42
  root: Panda::CMS::Engine.root.join("public")
50
- )
43
+
44
+ # Make JavaScript files available for importmap
45
+ # Serve from app/javascript with proper MIME types
46
+ config.middleware.use Rack::Static,
47
+ urls: ["/panda/cms"],
48
+ root: Panda::CMS::Engine.root.join("app/javascript"),
49
+ header_rules: [
50
+ [:all, {"Cache-Control" => Rails.env.development? ? "no-cache, no-store, must-revalidate" : "public, max-age=31536000",
51
+ "Content-Type" => "text/javascript; charset=utf-8"}]
52
+ ]
51
53
 
52
54
  # Custom error handling
53
55
  # config.exceptions_app = Panda::CMS::ExceptionsApp.new(exceptions_app: routes)
@@ -86,13 +88,22 @@ module Panda
86
88
  end
87
89
  end
88
90
 
91
+ # Auto-mount CMS routes
89
92
  config.after_initialize do |app|
90
93
  # Append routes to the routes file
91
94
  app.routes.append do
92
95
  mount Panda::CMS::Engine => "/", :as => "panda_cms"
93
96
  post "/_forms/:id", to: "panda/cms/form_submissions#create", as: :panda_cms_form_submit
94
97
  get "/_maintenance", to: "panda/cms/errors#error_503", as: :panda_cms_maintenance
95
- get "/*path", to: "panda/cms/pages#show", as: :panda_cms_page
98
+
99
+ # Catch-all route for CMS pages, but exclude admin paths and assets
100
+ admin_path = Panda::Core.config.admin_path.delete_prefix("/")
101
+ constraints = ->(request) {
102
+ !request.path.start_with?("/#{admin_path}") &&
103
+ !request.path.start_with?("/panda-cms-assets/")
104
+ }
105
+ get "/*path", to: "panda/cms/pages#show", as: :panda_cms_page, constraints: constraints
106
+
96
107
  root to: "panda/cms/pages#root"
97
108
  end
98
109
  end
@@ -131,63 +142,111 @@ module Panda
131
142
  app.config.view_component.preview_paths << root.join("spec/components/previews")
132
143
  app.config.view_component.generate.sidecar = true
133
144
  app.config.view_component.generate.preview = true
145
+
146
+ # Add preview directories to autoload paths in development
147
+ if Rails.env.development?
148
+ # Handle frozen autoload_paths array
149
+ if app.config.autoload_paths.frozen?
150
+ app.config.autoload_paths = app.config.autoload_paths.dup
151
+ end
152
+ app.config.autoload_paths << root.join("spec/components/previews")
153
+ end
134
154
  end
135
155
 
136
156
  # Authentication is now handled by Panda::Core::Engine
137
157
 
138
- # Configure Core for CMS
139
- initializer "panda.cms.configure_core" do |app|
158
+ # Configure Core for CMS (runs before app initializers so apps can override)
159
+ initializer "panda.cms.configure_core", before: :load_config_initializers do |app|
140
160
  Panda::Core.configure do |config|
141
- # Customize login page
142
- config.login_logo_path = "/panda-cms-assets/panda-nav.png"
143
- config.login_page_title = "Panda CMS Admin"
161
+ # Core now provides the admin interface foundation
162
+ # Apps using CMS can customize login_logo_path, login_page_title, etc. in their own initializers
163
+
164
+ # Register CMS navigation items
165
+ config.admin_navigation_items = ->(user) {
166
+ items = []
167
+
168
+ # Dashboard
169
+ items << {
170
+ path: "#{config.admin_path}/cms",
171
+ label: "Dashboard",
172
+ icon: "fa-solid fa-house"
173
+ }
174
+
175
+ # Pages
176
+ items << {
177
+ path: "#{config.admin_path}/cms/pages",
178
+ label: "Pages",
179
+ icon: "fa-solid fa-file"
180
+ }
181
+
182
+ # Collections (if enabled)
183
+ if Panda::CMS::Features.enabled?(:collections)
184
+ items << {
185
+ path: "#{config.admin_path}/cms/collections",
186
+ label: "Collections",
187
+ icon: "fa-solid fa-table-cells"
188
+ }
189
+ end
190
+
191
+ # Posts
192
+ items << {
193
+ path: "#{config.admin_path}/cms/posts",
194
+ label: "Posts",
195
+ icon: "fa-solid fa-newspaper"
196
+ }
197
+
198
+ # Forms
199
+ items << {
200
+ path: "#{config.admin_path}/cms/forms",
201
+ label: "Forms",
202
+ icon: "fa-solid fa-inbox"
203
+ }
204
+
205
+ # Files
206
+ items << {
207
+ path: "#{config.admin_path}/cms/files",
208
+ label: "Files",
209
+ icon: "fa-solid fa-image"
210
+ }
211
+
212
+ # Menus
213
+ items << {
214
+ path: "#{config.admin_path}/cms/menus",
215
+ label: "Menus",
216
+ icon: "fa-solid fa-bars"
217
+ }
218
+
219
+ # Settings
220
+ items << {
221
+ path: "#{config.admin_path}/cms/settings",
222
+ label: "Settings",
223
+ icon: "fa-solid fa-gear"
224
+ }
225
+
226
+ items
227
+ }
144
228
 
145
- # Set dashboard redirect path to CMS dashboard (using Core's admin_path)
146
- config.dashboard_redirect_path = "#{Panda::Core.configuration.admin_path}/cms"
229
+ # Redirect to CMS dashboard after login
230
+ # Apps can override this if they want different behavior
231
+ config.dashboard_redirect_path = -> { "#{Panda::Core.config.admin_path}/cms" }
147
232
 
148
233
  # Customize initial breadcrumb
149
234
  config.initial_admin_breadcrumb = ->(controller) {
150
235
  # Use CMS dashboard path - just use the string path
151
- ["Admin", "#{Panda::Core.configuration.admin_path}/cms"]
236
+ ["Admin", "#{config.admin_path}/cms"]
152
237
  }
153
238
 
154
239
  # Dashboard widgets
155
240
  config.admin_dashboard_widgets = ->(user) {
156
241
  widgets = []
157
242
 
158
- # Add CMS statistics widgets if CMS is available
159
- if defined?(Panda::CMS)
160
- widgets << Panda::CMS::Admin::StatisticsComponent.new(
161
- metric: "Views Today",
162
- value: Panda::CMS::Visit.group_by_day(:visited_at, last: 1).count.values.first || 0
163
- )
164
- widgets << Panda::CMS::Admin::StatisticsComponent.new(
165
- metric: "Views Last Week",
166
- value: Panda::CMS::Visit.group_by_week(:visited_at, last: 1).count.values.first || 0
167
- )
168
- widgets << Panda::CMS::Admin::StatisticsComponent.new(
169
- metric: "Views Last Month",
170
- value: Panda::CMS::Visit.group_by_month(:visited_at, last: 1).count.values.first || 0
171
- )
172
- end
243
+ # TODO: Add CMS statistics widgets when StatisticsComponent is implemented
244
+ # This was removed along with Pro code migration
173
245
 
174
246
  widgets
175
247
  }
176
248
  end
177
249
  end
178
-
179
- config.before_initialize do |_app|
180
- # Default configuration
181
- Panda::CMS.configure do |config|
182
- # Array of additional EditorJS tools to load
183
- # Example: [{ url: "https://cdn.jsdelivr.net/npm/@editorjs/image@latest" }]
184
- config.editor_js_tools ||= []
185
-
186
- # Hash of EditorJS tool configurations
187
- # Example: { image: { class: 'ImageTool', config: { ... } } }
188
- config.editor_js_tool_config ||= {}
189
- end
190
- end
191
250
  end
192
251
 
193
252
  class MissingBlockError < StandardError; end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Panda
4
+ module CMS
5
+ # Lightweight feature flag registry so open-source core can gate functionality
6
+ # that is only available when panda-cms-pro is installed.
7
+ module Features
8
+ Feature = Struct.new(:name, :provider, keyword_init: true)
9
+
10
+ class MissingFeatureError < StandardError; end
11
+
12
+ class << self
13
+ def register(name, provider:)
14
+ registry[name.to_sym] = Feature.new(name: name.to_sym, provider: provider)
15
+ end
16
+
17
+ def unregister(name)
18
+ registry.delete(name.to_sym)
19
+ end
20
+
21
+ def reset!
22
+ registry.clear
23
+ end
24
+
25
+ def enabled?(name)
26
+ registry.key?(name.to_sym)
27
+ end
28
+
29
+ def require!(name)
30
+ return if enabled?(name)
31
+
32
+ raise MissingFeatureError,
33
+ "The #{name} feature is only available with panda-cms-pro."
34
+ end
35
+
36
+ def provider_for(name)
37
+ registry[name.to_sym]&.provider
38
+ end
39
+
40
+ def enabled_features
41
+ registry.keys
42
+ end
43
+
44
+ private
45
+
46
+ def registry
47
+ @registry ||= {}
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Panda
4
4
  module CMS
5
- VERSION = "0.8.0"
5
+ VERSION = "0.10.0"
6
6
  end
7
7
  end
data/lib/panda-cms.rb CHANGED
@@ -9,8 +9,7 @@ module Panda
9
9
  module CMS
10
10
  class Configuration
11
11
  attr_accessor :title, :require_login_to_view, :authentication,
12
- :posts, :url, :editor_js_tools,
13
- :editor_js_tool_config, :instagram, :analytics
12
+ :posts, :url, :instagram, :analytics
14
13
 
15
14
  def initialize
16
15
  @title = "Demo Site"
@@ -18,8 +17,6 @@ module Panda
18
17
  @authentication = {}
19
18
  @posts = {enabled: true, prefix: "blog"}
20
19
  @url = nil
21
- @editor_js_tools = []
22
- @editor_js_tool_config = {}
23
20
  @instagram = {
24
21
  enabled: false,
25
22
  username: nil,
@@ -56,7 +53,7 @@ module Panda
56
53
 
57
54
  def self.root_path
58
55
  # Delegate to Panda::Core's admin_path configuration
59
- Panda::Core.configuration.admin_path
56
+ Panda::Core.config.admin_path
60
57
  end
61
58
 
62
59
  class << self
@@ -64,7 +61,7 @@ module Panda
64
61
 
65
62
  def route_namespace
66
63
  # Delegate to Panda::Core's admin_path configuration
67
- Panda::Core.configuration.admin_path
64
+ Panda::Core.config.admin_path
68
65
  end
69
66
  end
70
67
  end
@@ -91,10 +88,12 @@ Panda::CMS.loader.inflector.inflect(
91
88
 
92
89
  # Manually require files from panda-cms directory
93
90
  require_relative "panda-cms/version"
91
+ require_relative "panda/cms/debug"
94
92
  require_relative "panda/cms/exceptions_app"
95
93
  require_relative "panda/cms/engine"
96
94
  require_relative "panda/cms/demo_site_generator"
97
95
  require_relative "panda/cms/asset_loader"
96
+ require_relative "panda/cms/features"
98
97
  require_relative "panda/cms/slug"
99
98
 
100
99
  Panda::CMS.loader.setup
@@ -23,13 +23,8 @@ namespace :panda do
23
23
  File.write(js_file, js_bundle)
24
24
  puts "✅ JavaScript compiled: #{js_file} (#{File.size(js_file)} bytes)"
25
25
 
26
- # Compile CSS bundle (if any CSS files exist)
27
- css_bundle = compile_css_bundle(version)
28
- if css_bundle && !css_bundle.strip.empty?
29
- css_file = output_dir.join("panda-cms-#{version}.css")
30
- File.write(css_file, css_bundle)
31
- puts "✅ CSS compiled: #{css_file} (#{File.size(css_file)} bytes)"
32
- end
26
+ # CSS is now provided by Panda Core
27
+ puts "ℹ️ CSS is provided by Panda Core at /panda-core-assets/panda-core.css"
33
28
 
34
29
  # Create manifest file
35
30
  manifest = create_asset_manifest(version)
@@ -43,7 +38,6 @@ namespace :panda do
43
38
  FileUtils.mkdir_p(test_asset_dir)
44
39
 
45
40
  js_file_name = "panda-cms-#{version}.js"
46
- css_file_name = "panda-cms-#{version}.css"
47
41
 
48
42
  # Copy JavaScript file
49
43
  if File.exist?(output_dir.join(js_file_name))
@@ -51,12 +45,6 @@ namespace :panda do
51
45
  puts "✅ Copied JavaScript to test location: #{test_asset_dir.join(js_file_name)}"
52
46
  end
53
47
 
54
- # Copy CSS file
55
- if File.exist?(output_dir.join(css_file_name))
56
- FileUtils.cp(output_dir.join(css_file_name), test_asset_dir.join(css_file_name))
57
- puts "✅ Copied CSS to test location: #{test_asset_dir.join(css_file_name)}"
58
- end
59
-
60
48
  # Copy manifest
61
49
  if File.exist?(output_dir.join("manifest.json"))
62
50
  FileUtils.cp(output_dir.join("manifest.json"), test_asset_dir.join("manifest.json"))
@@ -186,44 +174,9 @@ def compile_javascript_bundle(version)
186
174
  bundle.join("\n")
187
175
  end
188
176
 
189
- def compile_css_bundle(version)
190
- puts "Creating simplified CSS bundle for CI testing..."
191
-
192
- # Create a minimal CSS bundle with basic styles
193
- bundle = []
194
- bundle << "/* Panda CMS CSS Bundle v#{version} */"
195
- bundle << "/* Compiled: #{Time.now.utc.iso8601} */"
196
- bundle << "/* This is a simplified bundle for CI testing purposes */"
197
- bundle << ""
198
-
199
- # Add some basic styles that might be expected
200
- bundle << "/* Basic Panda CMS Styles */"
201
- bundle << ".panda-cms-admin {"
202
- bundle << " font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;"
203
- bundle << " line-height: 1.5;"
204
- bundle << "}"
205
- bundle << ""
206
- bundle << ".panda-cms-editor {"
207
- bundle << " min-height: 200px;"
208
- bundle << " border: 1px solid #e5e7eb;"
209
- bundle << " border-radius: 0.375rem;"
210
- bundle << " padding: 1rem;"
211
- bundle << "}"
212
- bundle << ""
213
- bundle << ".panda-cms-hidden {"
214
- bundle << " display: none !important;"
215
- bundle << "}"
216
- bundle << ""
217
- bundle << "/* Editor ready state */"
218
- bundle << ".editor-ready {"
219
- bundle << " opacity: 1;"
220
- bundle << " transition: opacity 0.3s ease-in-out;"
221
- bundle << "}"
222
- bundle << ""
223
-
224
- puts "✅ Created simplified CSS bundle (#{bundle.join("\n").length} chars)"
225
- bundle.join("\n")
226
- end
177
+ # CSS compilation removed - all CSS is now provided by Panda Core
178
+ # The panda-core.css file includes all admin interface styling including
179
+ # EditorJS styles, theme variables, and component styles
227
180
 
228
181
  def create_asset_manifest(version)
229
182
  output_dir = Rails.root.join("tmp", "panda_cms_assets")
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Provide consistent namespacing for Panda tasks
4
+ # Rails auto-generates panda_cms:* tasks from the module name,
5
+ # but we want to use panda:cms:* for consistency across all Panda gems
6
+
7
+ namespace :panda do
8
+ namespace :cms do
9
+ namespace :install do
10
+ desc "Copy migrations from panda-cms to application"
11
+ task :migrations do
12
+ Rake::Task["panda_cms:install:migrations"].invoke
13
+ end
14
+ end
15
+ end
16
+ end