panda-cms 0.7.5 → 0.8.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/app/components/panda/cms/admin/user_activity_component.html.erb +2 -2
  3. data/app/components/panda/cms/admin/user_activity_component.rb +2 -2
  4. data/app/components/panda/cms/admin/user_display_component.html.erb +1 -1
  5. data/app/components/panda/cms/admin/user_display_component.rb +2 -2
  6. data/app/components/panda/cms/rich_text_component.rb +5 -5
  7. data/app/controllers/panda/cms/admin/base_controller.rb +18 -0
  8. data/app/controllers/panda/cms/admin/block_contents_controller.rb +1 -2
  9. data/app/controllers/panda/cms/admin/dashboard_controller.rb +5 -4
  10. data/app/controllers/panda/cms/admin/files_controller.rb +1 -3
  11. data/app/controllers/panda/cms/admin/forms_controller.rb +3 -4
  12. data/app/controllers/panda/cms/admin/menus_controller.rb +2 -3
  13. data/app/controllers/panda/cms/admin/pages_controller.rb +7 -7
  14. data/app/controllers/panda/cms/admin/posts_controller.rb +9 -10
  15. data/app/controllers/panda/cms/admin/settings/bulk_editor_controller.rb +4 -4
  16. data/app/controllers/panda/cms/admin/settings_controller.rb +2 -3
  17. data/app/controllers/panda/cms/application_controller.rb +13 -5
  18. data/app/controllers/panda/cms/pages_controller.rb +2 -2
  19. data/app/helpers/panda/cms/application_helper.rb +3 -3
  20. data/app/helpers/panda/cms/asset_helper.rb +14 -1
  21. data/app/javascript/panda/cms/application_panda_cms.js +2 -34
  22. data/app/javascript/panda/cms/controllers/index.js +5 -15
  23. data/app/models/panda/cms/block_content.rb +1 -1
  24. data/app/models/panda/cms/current.rb +3 -12
  25. data/app/models/panda/cms/post.rb +3 -3
  26. data/app/models/panda/cms/visit.rb +1 -1
  27. data/app/views/layouts/panda/cms/application.html.erb +1 -1
  28. data/app/views/panda/cms/admin/dashboard/show.html.erb +2 -2
  29. data/app/views/panda/cms/admin/files/index.html.erb +1 -1
  30. data/app/views/panda/cms/admin/forms/index.html.erb +4 -4
  31. data/app/views/panda/cms/admin/forms/new.html.erb +2 -2
  32. data/app/views/panda/cms/admin/forms/show.html.erb +1 -1
  33. data/app/views/panda/cms/admin/menus/index.html.erb +4 -4
  34. data/app/views/panda/cms/admin/pages/edit.html.erb +6 -6
  35. data/app/views/panda/cms/admin/pages/index.html.erb +5 -5
  36. data/app/views/panda/cms/admin/pages/new.html.erb +2 -2
  37. data/app/views/panda/cms/admin/posts/_form.html.erb +1 -1
  38. data/app/views/panda/cms/admin/posts/edit.html.erb +2 -2
  39. data/app/views/panda/cms/admin/posts/index.html.erb +5 -5
  40. data/app/views/panda/cms/admin/posts/new.html.erb +1 -1
  41. data/app/views/panda/cms/admin/settings/bulk_editor/new.html.erb +1 -1
  42. data/app/views/panda/cms/admin/settings/index.html.erb +3 -3
  43. data/app/views/panda/cms/admin/shared/_breadcrumbs.html.erb +3 -3
  44. data/app/views/panda/cms/admin/shared/_flash.html.erb +1 -1
  45. data/app/views/panda/cms/admin/shared/_sidebar.html.erb +8 -8
  46. data/config/initializers/panda/cms.rb +6 -3
  47. data/config/routes.rb +8 -16
  48. data/db/migrate/20250106223303_add_author_id_to_panda_cms_posts.rb +3 -1
  49. data/db/migrate/20250126234001_create_panda_social_instagram_posts.rb +2 -0
  50. data/db/migrate/20250809231125_migrate_users_to_panda_core.rb +111 -0
  51. data/db/migrate/20250811111000_make_post_user_references_nullable.rb +11 -0
  52. data/lib/panda/cms/asset_loader.rb +4 -4
  53. data/lib/panda/cms/engine.rb +42 -98
  54. data/lib/panda-cms/version.rb +1 -1
  55. data/lib/panda-cms.rb +50 -40
  56. data/lib/tasks/assets.rake +162 -122
  57. data/lib/tasks/panda/cms/migrations.rake +13 -0
  58. metadata +19 -36
  59. data/app/builders/panda/cms/form_builder.rb +0 -225
  60. data/app/components/panda/cms/admin/button_component.rb +0 -70
  61. data/app/components/panda/cms/admin/container_component.rb +0 -13
  62. data/app/components/panda/cms/admin/flash_message_component.rb +0 -47
  63. data/app/components/panda/cms/admin/heading_component.rb +0 -46
  64. data/app/components/panda/cms/admin/panel_component.rb +0 -13
  65. data/app/components/panda/cms/admin/table_component.rb +0 -46
  66. data/app/components/panda/cms/admin/tag_component.rb +0 -35
  67. data/app/constraints/panda/cms/admin_constraint.rb +0 -21
  68. data/app/controllers/panda/cms/admin/my_profile_controller.rb +0 -44
  69. data/app/controllers/panda/cms/admin/sessions_controller.rb +0 -92
  70. data/app/javascript/panda/cms/controllers/theme_form_controller.js +0 -25
  71. data/app/javascript/panda/cms/editor/css_extractor.js +0 -80
  72. data/app/javascript/panda/cms/editor/editor_js_config.js +0 -306
  73. data/app/javascript/panda/cms/editor/editor_js_initializer.js +0 -334
  74. data/app/javascript/panda/cms/editor/plain_text_editor.js +0 -110
  75. data/app/javascript/panda/cms/editor/resource_loader.js +0 -204
  76. data/app/javascript/panda/cms/editor/rich_text_editor.js +0 -162
  77. data/app/models/panda/cms/breadcrumb.rb +0 -14
  78. data/app/models/panda/cms/user.rb +0 -33
  79. data/app/services/panda/cms/html_to_editor_js_converter.rb +0 -195
  80. data/app/views/panda/cms/admin/my_profile/edit.html.erb +0 -35
  81. data/app/views/panda/cms/admin/sessions/new.html.erb +0 -17
  82. data/db/migrate/20250504221812_add_current_theme_to_panda_cms_users.rb +0 -7
  83. data/lib/panda/cms/editor_js/blocks/alert.rb +0 -36
  84. data/lib/panda/cms/editor_js/blocks/base.rb +0 -35
  85. data/lib/panda/cms/editor_js/blocks/header.rb +0 -17
  86. data/lib/panda/cms/editor_js/blocks/image.rb +0 -39
  87. data/lib/panda/cms/editor_js/blocks/list.rb +0 -34
  88. data/lib/panda/cms/editor_js/blocks/paragraph.rb +0 -18
  89. data/lib/panda/cms/editor_js/blocks/quote.rb +0 -44
  90. data/lib/panda/cms/editor_js/blocks/table.rb +0 -52
  91. data/lib/panda/cms/editor_js/renderer.rb +0 -127
  92. data/lib/panda/cms/editor_js.rb +0 -18
  93. data/lib/panda/cms/editor_js_content.rb +0 -61
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a11a8249369ac564953d025d4887020ced356b6357a5d8c823580c27e39394cb
4
- data.tar.gz: 04d6f8dab1ae48f77414ea10b515739f36a54c0f37b79e82f7d9282305af03a1
3
+ metadata.gz: 9a439141e4b2fd9c4167ea0bd872096a648fe1a9fcfc237e6a1c20e16d2a2562
4
+ data.tar.gz: fa28c3d1d698b9725140618603505a0120c0e58430ff4c923ccd986f3e27daa5
5
5
  SHA512:
6
- metadata.gz: eb71f7f01ba585e142738e5d28510c5a0508b69843aab7c5b60fbf5cbaa7bb89419a916df923d0282cd2311a61614d836002635e67b9d6dfadd4bd6dba4e3f81
7
- data.tar.gz: a795545501c2633b3e911b93ccd5c302adbb7d9c9f5a0ab6c363196ae4e0d18089a2b99cc3ada4b66e44902c8a5828212251b331e1b8b4d4762dfafef74dfe0f
6
+ metadata.gz: 1923aea63bd5a266487a4a25e852df4cc96e0cba408fd9cb9351a5a302a20ad7e07ef22254dbe01ef7751ca3b35d0a9cdfb941a821e56730455fc73f0223083b
7
+ data.tar.gz: 54291d3de7b95047412a2c6c9e50b94f187457803bfd1609f0f9a947348de612c2ca6480f33e8e5df5f0305c131d638e025f1d6e04cc30c2997ce4ccb2a9c56e
@@ -1,6 +1,6 @@
1
- <% if user.is_a?(Panda::CMS::User) && time %>
1
+ <% if user.is_a?(Panda::Core::User) && time %>
2
2
  <%= render Panda::CMS::Admin::UserDisplayComponent.new(user: user, metadata: "#{time_ago_in_words(time)} ago") %>
3
- <% elsif user.is_a?(Panda::CMS::User) %>
3
+ <% elsif user.is_a?(Panda::Core::User) %>
4
4
  <%= render Panda::CMS::Admin::UserDisplayComponent.new(user: user, metadata: "Not published") %>
5
5
  <% elsif time %>
6
6
  <div class="text-black/60"><%= time_ago_in_words(time) %> ago</div>
@@ -8,10 +8,10 @@ module Panda
8
8
 
9
9
  # @param model [ActiveRecord::Base] Model instance to which the user activity is related
10
10
  # @param at [ActiveSupport::TimeWithZone] Time of the activity
11
- # @param user [Panda::CMS::User] User who performed the activity
11
+ # @param user [Panda::Core::User] User who performed the activity
12
12
  def initialize(model: nil, at: nil, user: nil)
13
13
  @model = model
14
- @user = user if user.is_a?(::Panda::CMS::User)
14
+ @user = user if user.is_a?(::Panda::Core::User)
15
15
  @time = at if at.is_a?(::ActiveSupport::TimeWithZone)
16
16
  end
17
17
  end
@@ -10,7 +10,7 @@
10
10
  </div>
11
11
  <% end %>
12
12
  <div class="ml-3">
13
- <p class="text-sm text-black"><%= user.firstname %> <%= user.lastname %></p>
13
+ <p class="text-sm text-black"><%= user.name %></p>
14
14
  <% if metadata %><p class="text-sm text-black/60"><%= metadata %></p><% end %>
15
15
  </div>
16
16
  </div>
@@ -7,8 +7,8 @@ module Panda
7
7
  attr_accessor :user_id, :user, :metadata
8
8
 
9
9
  def initialize(user_id: nil, user: nil, metadata: "")
10
- @user = if user.nil? && user_id.present? && Panda::CMS::User.find(user_id)
11
- Panda::CMS::User.find(user_id)
10
+ @user = if user.nil? && user_id.present? && Panda::Core::User.find(user_id)
11
+ Panda::Core::User.find(user_id)
12
12
  else
13
13
  user
14
14
  end
@@ -78,13 +78,13 @@ module Panda
78
78
  else
79
79
  # If not valid EditorJS, try to convert from HTML
80
80
  begin
81
- editor_content = Panda::CMS::HtmlToEditorJsConverter.convert(@content)
81
+ editor_content = Panda::Editor::HtmlToEditorJsConverter.convert(@content)
82
82
  if valid_editor_js_content?(editor_content)
83
83
  editor_content
84
84
  else
85
85
  empty_editor_js_content
86
86
  end
87
- rescue Panda::CMS::HtmlToEditorJsConverter::ConversionError => e
87
+ rescue Panda::Editor::HtmlToEditorJsConverter::ConversionError => e
88
88
  Rails.logger.error("HTML conversion error: #{e.message}")
89
89
  empty_editor_js_content
90
90
  end
@@ -93,13 +93,13 @@ module Panda
93
93
  Rails.logger.error("JSON parse error: #{e.message}")
94
94
  # Try to convert from HTML
95
95
  begin
96
- editor_content = Panda::CMS::HtmlToEditorJsConverter.convert(@content)
96
+ editor_content = Panda::Editor::HtmlToEditorJsConverter.convert(@content)
97
97
  if valid_editor_js_content?(editor_content)
98
98
  editor_content
99
99
  else
100
100
  empty_editor_js_content
101
101
  end
102
- rescue Panda::CMS::HtmlToEditorJsConverter::ConversionError => e
102
+ rescue Panda::Editor::HtmlToEditorJsConverter::ConversionError => e
103
103
  Rails.logger.error("HTML conversion error: #{e.message}")
104
104
  empty_editor_js_content
105
105
  end
@@ -129,7 +129,7 @@ module Panda
129
129
  parsed_content["blocks"][0]["data"]["text"].blank?
130
130
  "<p></p>".html_safe
131
131
  else
132
- renderer = Panda::CMS::EditorJs::Renderer.new(parsed_content)
132
+ renderer = Panda::Editor::Renderer.new(parsed_content)
133
133
  rendered = renderer.render
134
134
  rendered.presence&.html_safe || "<p></p>".html_safe
135
135
  end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Panda
4
+ module CMS
5
+ module Admin
6
+ # Base controller for all CMS admin controllers
7
+ # Inherits from Core AdminController for authentication
8
+ # Adds CMS-specific helpers and functionality
9
+ class BaseController < ::Panda::Core::AdminController
10
+ # Include CMS helpers so views have access to panda_cms_form_with, etc.
11
+ helper Panda::CMS::ApplicationHelper
12
+
13
+ # Include the helper methods in the controller as well
14
+ include Panda::CMS::ApplicationHelper
15
+ end
16
+ end
17
+ end
18
+ end
@@ -3,10 +3,9 @@
3
3
  module Panda
4
4
  module CMS
5
5
  module Admin
6
- class BlockContentsController < ApplicationController
6
+ class BlockContentsController < ::Panda::CMS::Admin::BaseController
7
7
  before_action :set_page, only: %i[update]
8
8
  before_action :set_block_content, only: %i[update]
9
- before_action :authenticate_admin_user!
10
9
 
11
10
  # @type PATCH/PUT
12
11
  # @return
@@ -5,18 +5,19 @@ require "groupdate"
5
5
  module Panda
6
6
  module CMS
7
7
  module Admin
8
- class DashboardController < ApplicationController
8
+ class DashboardController < ::Panda::Core::Admin::DashboardController
9
9
  before_action :set_initial_breadcrumb, only: %i[show]
10
- before_action :authenticate_admin_user!
11
10
 
12
- # GET /admin
11
+ # Override the panda-core dashboard with CMS-specific dashboard
13
12
  def show
13
+ # Render the CMS dashboard view
14
+ render "panda/cms/admin/dashboard/show"
14
15
  end
15
16
 
16
17
  private
17
18
 
18
19
  def set_initial_breadcrumb
19
- add_breadcrumb "Dashboard", Panda::CMS.route_namespace
20
+ add_breadcrumb "Dashboard", admin_cms_dashboard_path
20
21
  end
21
22
  end
22
23
  end
@@ -3,9 +3,7 @@
3
3
  module Panda
4
4
  module CMS
5
5
  module Admin
6
- class FilesController < ApplicationController
7
- before_action :authenticate_admin_user!
8
-
6
+ class FilesController < ::Panda::CMS::Admin::BaseController
9
7
  def create
10
8
  file = params[:image]
11
9
  return render json: {success: 0} unless file
@@ -3,9 +3,8 @@
3
3
  module Panda
4
4
  module CMS
5
5
  module Admin
6
- class FormsController < ApplicationController
6
+ class FormsController < ::Panda::CMS::Admin::BaseController
7
7
  before_action :set_initial_breadcrumb, only: %i[index show]
8
- before_action :authenticate_admin_user!
9
8
 
10
9
  # Lists all forms
11
10
  # @type GET
@@ -18,7 +17,7 @@ module Panda
18
17
  def show
19
18
  form = Panda::CMS::Form.find(params[:id])
20
19
 
21
- add_breadcrumb form.name, admin_form_path(form)
20
+ add_breadcrumb form.name, admin_cms_form_path(form)
22
21
  submissions = form.form_submissions.order(created_at: :desc)
23
22
  # TODO: Set a whitelist of fields we allow to be submitted for the form, shown in this view
24
23
  # and a formatting array of how to display them... eventually?
@@ -35,7 +34,7 @@ module Panda
35
34
  private
36
35
 
37
36
  def set_initial_breadcrumb
38
- add_breadcrumb "Forms", admin_forms_path
37
+ add_breadcrumb "Forms", admin_cms_forms_path
39
38
  end
40
39
 
41
40
  # Only allow a list of trusted parameters through
@@ -3,9 +3,8 @@
3
3
  module Panda
4
4
  module CMS
5
5
  module Admin
6
- class MenusController < ApplicationController
6
+ class MenusController < ::Panda::CMS::Admin::BaseController
7
7
  before_action :set_initial_breadcrumb, only: %i[index]
8
- before_action :authenticate_admin_user!
9
8
 
10
9
  # Lists all menus which can be managed by the administrator
11
10
  # @type GET
@@ -22,7 +21,7 @@ module Panda
22
21
  end
23
22
 
24
23
  def set_initial_breadcrumb
25
- add_breadcrumb "Menus", admin_menus_path
24
+ add_breadcrumb "Menus", admin_cms_menus_path
26
25
  end
27
26
  end
28
27
  end
@@ -3,9 +3,9 @@
3
3
  module Panda
4
4
  module CMS
5
5
  module Admin
6
- class PagesController < ApplicationController
6
+ class PagesController < ::Panda::CMS::Admin::BaseController
7
7
  before_action :set_initial_breadcrumb, only: %i[index edit new create update]
8
- before_action :authenticate_admin_user!
8
+ # Authentication is automatically enforced by AdminController
9
9
 
10
10
  # Lists all pages which can be managed by the administrator
11
11
  # @type GET
@@ -25,7 +25,7 @@ module Panda
25
25
  # Loads the page editor
26
26
  # @type GET
27
27
  def edit
28
- add_breadcrumb page.title, edit_admin_page_path(page)
28
+ add_breadcrumb page.title, edit_admin_cms_page_path(page)
29
29
 
30
30
  render :edit, locals: {page: page, template: page.template}
31
31
  end
@@ -44,7 +44,7 @@ module Panda
44
44
  end
45
45
 
46
46
  if page.save
47
- redirect_to edit_admin_page_path(page), notice: "The page was successfully created."
47
+ redirect_to edit_admin_cms_page_path(page), notice: "The page was successfully created."
48
48
  else
49
49
  flash.now[:error] = page.errors.full_messages.to_sentence
50
50
  locals = setup_new_page_form(page: page)
@@ -56,7 +56,7 @@ module Panda
56
56
  # @return
57
57
  def update
58
58
  if page.update(page_params)
59
- redirect_to edit_admin_page_path(page),
59
+ redirect_to edit_admin_cms_page_path(page),
60
60
  status: :see_other,
61
61
  flash: {success: "This page was successfully updated!"}
62
62
  else
@@ -79,11 +79,11 @@ module Panda
79
79
  end
80
80
 
81
81
  def set_initial_breadcrumb
82
- add_breadcrumb "Pages", admin_pages_path
82
+ add_breadcrumb "Pages", admin_cms_pages_path
83
83
  end
84
84
 
85
85
  def setup_new_page_form(page:)
86
- add_breadcrumb "Add Page", new_admin_page_path
86
+ add_breadcrumb "Add Page", new_admin_cms_page_path
87
87
  {
88
88
  page: page,
89
89
  available_templates: Panda::CMS::Template.available
@@ -5,9 +5,8 @@ require "json"
5
5
  module Panda
6
6
  module CMS
7
7
  module Admin
8
- class PostsController < ApplicationController
8
+ class PostsController < ::Panda::CMS::Admin::BaseController
9
9
  before_action :set_initial_breadcrumb, only: %i[index edit new create update]
10
- before_action :authenticate_admin_user!
11
10
 
12
11
  # Get all posts
13
12
  # @type GET
@@ -27,7 +26,7 @@ module Panda
27
26
  # Loads the post editor
28
27
  # @type GET
29
28
  def edit
30
- add_breadcrumb post.title, edit_admin_post_path(post.admin_param)
29
+ add_breadcrumb post.title, edit_admin_cms_post_path(post.admin_param)
31
30
  render :edit, locals: {post: post}
32
31
  end
33
32
 
@@ -39,7 +38,7 @@ module Panda
39
38
 
40
39
  if @post.save
41
40
  Rails.logger.debug "Post saved successfully"
42
- redirect_to edit_admin_post_path(@post.admin_param), notice: "The post was successfully created!"
41
+ redirect_to edit_admin_cms_post_path(@post.admin_param), notice: "The post was successfully created!"
43
42
  else
44
43
  Rails.logger.debug "Post save failed: #{@post.errors.full_messages.inspect}"
45
44
  flash.now[:error] = @post.errors.full_messages.join(", ")
@@ -60,13 +59,13 @@ module Panda
60
59
  update_params[:user_id] = current_user.id
61
60
  if post.update(update_params)
62
61
  Rails.logger.debug "Post updated successfully"
63
- add_breadcrumb post.title, edit_admin_post_path(post.admin_param)
62
+ add_breadcrumb post.title, edit_admin_cms_post_path(post.admin_param)
64
63
  flash[:success] = "The post was successfully updated"
65
- redirect_to edit_admin_post_path(post.admin_param), status: :see_other
64
+ redirect_to edit_admin_cms_post_path(post.admin_param), status: :see_other
66
65
  else
67
66
  Rails.logger.debug "Post update failed: #{post.errors.full_messages.inspect}"
68
67
  Rails.logger.debug "Preserving content: #{post_params[:content].inspect}"
69
- add_breadcrumb post.title.presence || "Edit Post", edit_admin_post_path(post.admin_param)
68
+ add_breadcrumb post.title.presence || "Edit Post", edit_admin_cms_post_path(post.admin_param)
70
69
  flash.now[:error] = post.errors.full_messages.join(", ")
71
70
  render :edit, locals: {
72
71
  post: post,
@@ -92,11 +91,11 @@ module Panda
92
91
  end
93
92
 
94
93
  def set_initial_breadcrumb
95
- add_breadcrumb "Posts", admin_posts_path
94
+ add_breadcrumb "Posts", admin_cms_posts_path
96
95
  end
97
96
 
98
97
  def setup_new_post_form(post: nil, preserved_content: nil)
99
- add_breadcrumb "Add Post", new_admin_post_path
98
+ add_breadcrumb "Add Post", new_admin_cms_post_path
100
99
 
101
100
  post ||= Panda::CMS::Post.new(
102
101
  status: "active",
@@ -105,7 +104,7 @@ module Panda
105
104
 
106
105
  {
107
106
  post: post,
108
- url: admin_posts_path,
107
+ url: admin_cms_posts_path,
109
108
  preserved_content: preserved_content
110
109
  }
111
110
  end
@@ -4,7 +4,7 @@ module Panda
4
4
  module CMS
5
5
  module Admin
6
6
  module Settings
7
- class BulkEditorController < ApplicationController
7
+ class BulkEditorController < ::Panda::CMS::Admin::BaseController
8
8
  before_action :set_initial_breadcrumb, only: %i[new]
9
9
 
10
10
  def new
@@ -15,7 +15,7 @@ module Panda
15
15
  begin
16
16
  debug_output = BulkEditor.import(params[:site_content])
17
17
  rescue JSON::ParserError
18
- redirect_to admin_settings_bulk_editor_path,
18
+ redirect_to admin_cms_settings_bulk_editor_path,
19
19
  flash: {error: "Error parsing content; are you sure this update is valid? Reverting..."}
20
20
  return
21
21
  end
@@ -24,7 +24,7 @@ module Panda
24
24
  @json_data = BulkEditor.export
25
25
 
26
26
  if debug_output[:error].empty? && debug_output[:warning].empty? && debug_output[:success].empty?
27
- redirect_to admin_settings_bulk_editor_path, flash: {success: "No changes were found!"}
27
+ redirect_to admin_cms_settings_bulk_editor_path, flash: {success: "No changes were found!"}
28
28
  else
29
29
  @debug = debug_output
30
30
  render :new, flash: {warning: "Please review the output below for more information."}
@@ -34,7 +34,7 @@ module Panda
34
34
  private
35
35
 
36
36
  def set_initial_breadcrumb
37
- add_breadcrumb "Settings", admin_settings_path
37
+ add_breadcrumb "Settings", admin_cms_settings_path
38
38
  add_breadcrumb "Bulk Editor", "#"
39
39
  end
40
40
  end
@@ -3,9 +3,8 @@
3
3
  module Panda
4
4
  module CMS
5
5
  module Admin
6
- class SettingsController < ApplicationController
6
+ class SettingsController < ::Panda::CMS::Admin::BaseController
7
7
  before_action :set_initial_breadcrumb, only: %i[index show]
8
- before_action :authenticate_admin_user!
9
8
 
10
9
  def index
11
10
  end
@@ -16,7 +15,7 @@ module Panda
16
15
  private
17
16
 
18
17
  def set_initial_breadcrumb
19
- add_breadcrumb "Settings", admin_settings_path
18
+ add_breadcrumb "Settings", admin_cms_settings_path
20
19
  end
21
20
  end
22
21
  end
@@ -28,14 +28,22 @@ module Panda
28
28
  # Set the current request details
29
29
  # @return [void]
30
30
  def set_current_request_details
31
+ # Set Core current attributes
32
+ Panda::Core::Current.request_id = request.uuid
33
+ Panda::Core::Current.user_agent = request.user_agent
34
+ Panda::Core::Current.ip_address = request.ip
35
+ Panda::Core::Current.root = request.base_url
36
+ Panda::Core::Current.user ||= Panda::Core::User.find_by(id: session[:user_id]) if session[:user_id]
37
+
38
+ # Set CMS current attributes (inherits from Core so has access to all Core attributes)
31
39
  Panda::CMS::Current.request_id = request.uuid
32
40
  Panda::CMS::Current.user_agent = request.user_agent
33
41
  Panda::CMS::Current.ip_address = request.ip
34
42
  Panda::CMS::Current.root = request.base_url
43
+ Panda::CMS::Current.user = Panda::Core::Current.user
35
44
  Panda::CMS::Current.page = nil
36
- Panda::CMS::Current.user ||= User.find_by(id: session[:user_id]) if session[:user_id]
37
45
 
38
- Panda::CMS.config.url ||= Panda::CMS::Current.root
46
+ Panda::CMS.config.url ||= Panda::Core::Current.root
39
47
  end
40
48
 
41
49
  def authenticate_user!
@@ -45,17 +53,17 @@ module Panda
45
53
  def authenticate_admin_user!
46
54
  return if user_signed_in? && current_user.admin?
47
55
 
48
- redirect_to admin_login_path,
56
+ redirect_to panda_core.admin_login_path,
49
57
  flash: {error: "Please login to view this!"}
50
58
  end
51
59
 
52
60
  # Required for paper_trail and seems as good as convention these days
53
61
  def current_user
54
- Panda::CMS::Current.user
62
+ Panda::Core::Current.user
55
63
  end
56
64
 
57
65
  def user_signed_in?
58
- !!Panda::CMS::Current.user
66
+ !!Panda::Core::Current.user
59
67
  end
60
68
  end
61
69
  end
@@ -82,9 +82,9 @@ module Panda
82
82
  def record_visit
83
83
  RecordVisitJob.perform_later(
84
84
  path: request.path,
85
- user_id: Current.user&.id,
85
+ user_id: Panda::Core::Current.user&.id,
86
86
  redirect_id: @redirect&.id,
87
- page_id: Current.page&.id,
87
+ page_id: Panda::CMS::Current.page&.id,
88
88
  user_agent: request.user_agent,
89
89
  ip_address: request.remote_ip,
90
90
  referer: request.referer, # TODO: Fix the naming of this column
@@ -24,8 +24,8 @@ module Panda
24
24
  end
25
25
 
26
26
  def panda_cms_editor
27
- if Current.user&.admin
28
- content_tag(:a, "🐼", href: edit_admin_page_url(Current.page), class: "text-3xl inline absolute right-2 top-2")
27
+ if Panda::Core::Current.user&.admin
28
+ content_tag(:a, "🐼", href: edit_admin_cms_page_url(Panda::CMS::Current.page), class: "text-3xl inline absolute right-2 top-2")
29
29
  end
30
30
  end
31
31
 
@@ -45,7 +45,7 @@ module Panda
45
45
  end
46
46
 
47
47
  def panda_cms_form_with(**options, &)
48
- options[:builder] = Panda::CMS::FormBuilder
48
+ options[:builder] = Panda::Core::FormBuilder
49
49
  options[:class] = ["block visible p-6 bg-mid/5 rounded-lg border-mid border", options[:class]].compact.join(" ")
50
50
  form_with(**options, &)
51
51
  end
@@ -1,13 +1,26 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "panda/core"
4
+
3
5
  module Panda
4
6
  module CMS
5
7
  module AssetHelper
8
+ include Panda::Core::AssetHelper if defined?(Panda::Core::AssetHelper)
6
9
  # Include Panda CMS JavaScript and CSS assets
7
10
  # Automatically chooses between GitHub-hosted assets (production)
8
11
  # and local development assets
9
12
  def panda_cms_assets
10
- Panda::CMS::AssetLoader.asset_tags.html_safe
13
+ tags = []
14
+
15
+ # Include Core assets first (if Core is available)
16
+ if defined?(Panda::Core::AssetHelper)
17
+ tags << panda_core_assets
18
+ end
19
+
20
+ # Then include CMS-specific assets
21
+ tags << Panda::CMS::AssetLoader.asset_tags
22
+
23
+ tags.join("\n").html_safe
11
24
  end
12
25
 
13
26
  # Include only Panda CMS JavaScript
@@ -3,37 +3,5 @@ console.debug("[Panda CMS] Controllers loading...");
3
3
  import "controllers"
4
4
  console.debug("[Panda CMS] Controllers loaded...");
5
5
 
6
- // Import editor resources
7
- import { EDITOR_JS_RESOURCES, EDITOR_JS_CSS } from "panda/cms/editor/editor_js_config"
8
- import { ResourceLoader } from "panda/cms/editor/resource_loader"
9
-
10
- // Function to load editor resources
11
- async function loadEditorResources() {
12
- console.debug("[Panda CMS] Loading editor resources...");
13
- try {
14
- // First load EditorJS core
15
- const editorCore = EDITOR_JS_RESOURCES[0]
16
- await ResourceLoader.loadScript(document, document.head, editorCore)
17
-
18
- // Then load all tools in parallel
19
- const toolLoads = EDITOR_JS_RESOURCES.slice(1).map(async (resource) => {
20
- await ResourceLoader.loadScript(document, document.head, resource)
21
- })
22
-
23
- // Load CSS directly since it's a string, not an array
24
- await ResourceLoader.embedCSS(document, document.head, EDITOR_JS_CSS)
25
-
26
- // Wait for all resources to load
27
- await Promise.all(toolLoads)
28
- console.debug("[Panda CMS] Editor resources loaded");
29
-
30
- // Dispatch a custom event when resources are loaded
31
- document.dispatchEvent(new CustomEvent('editorjs:loaded'))
32
- } catch (error) {
33
- console.error("[Panda CMS] Error loading editor resources:", error);
34
- }
35
- }
36
-
37
- // Load resources on both initial page load and Turbo cache restore
38
- document.addEventListener('turbo:load', loadEditorResources);
39
- document.addEventListener('turbo:render', loadEditorResources);
6
+ // Editor resources are now handled by panda-editor gem
7
+ // The panda-editor gem will load its own resources when needed
@@ -21,21 +21,11 @@ pandaCmsApplication.register("slug", SlugController)
21
21
  import EditorIframeController from "panda/cms/controllers/editor_iframe_controller"
22
22
  pandaCmsApplication.register("editor-iframe", EditorIframeController)
23
23
 
24
- console.debug("[Panda CMS] Registering components...")
25
- import ThemeFormController from "panda/cms/controllers/theme_form_controller";
26
- pandaCmsApplication.register("theme-form", ThemeFormController);
27
-
28
- // Import and register all TailwindCSS Components or just the ones you need
29
- import { Alert, Autosave, ColorPreview, Dropdown, Modal, Tabs, Popover, Toggle, Slideover } from "tailwindcss-stimulus-components"
30
- pandaCmsApplication.register('alert', Alert)
31
- pandaCmsApplication.register('autosave', Autosave)
32
- pandaCmsApplication.register('color-preview', ColorPreview)
33
- pandaCmsApplication.register('dropdown', Dropdown)
34
- pandaCmsApplication.register('modal', Modal)
35
- pandaCmsApplication.register('popover', Popover)
36
- pandaCmsApplication.register('slideover', Slideover)
37
- pandaCmsApplication.register('tabs', Tabs)
38
- pandaCmsApplication.register('toggle', Toggle)
24
+ // Import and register TailwindCSS Stimulus Components needed by CMS
25
+ import { Toggle } from "tailwindcss-stimulus-components"
26
+ pandaCmsApplication.register("toggle", Toggle)
27
+
28
+ console.debug("[Panda CMS] Registered Toggle controller for slideover functionality")
39
29
 
40
30
  console.debug("[Panda CMS] Components registered...")
41
31
 
@@ -3,7 +3,7 @@
3
3
  module Panda
4
4
  module CMS
5
5
  class BlockContent < ApplicationRecord
6
- include EditorJsContent
6
+ include ::Panda::Editor::Content
7
7
 
8
8
  self.table_name = "panda_cms_block_contents"
9
9
 
@@ -2,18 +2,9 @@
2
2
 
3
3
  module Panda
4
4
  module CMS
5
- class Current < ActiveSupport::CurrentAttributes
6
- attribute :root, :page
7
- attribute :user
8
- attribute :request_id, :user_agent, :ip_address
9
-
10
- # resets { Time.zone = nil }
11
-
12
- # def user=(user)
13
- # super
14
- # self.account = user.account
15
- # Time.zone = user.time_zone
16
- # end
5
+ class Current < Panda::Core::Current
6
+ # CMS-specific attributes
7
+ attribute :page
17
8
  end
18
9
  end
19
10
  end
@@ -5,15 +5,15 @@ require "awesome_nested_set"
5
5
  module Panda
6
6
  module CMS
7
7
  class Post < ApplicationRecord
8
- include ::Panda::CMS::EditorJsContent
8
+ include ::Panda::Editor::Content
9
9
 
10
10
  after_commit :clear_menu_cache
11
11
  before_validation :format_slug
12
12
 
13
13
  self.table_name = "panda_cms_posts"
14
14
 
15
- belongs_to :user, class_name: "Panda::CMS::User"
16
- belongs_to :author, class_name: "Panda::CMS::User", optional: true
15
+ belongs_to :user, class_name: "Panda::Core::User"
16
+ belongs_to :author, class_name: "Panda::Core::User", optional: true
17
17
  has_many :block_contents, as: :blockable, dependent: :destroy
18
18
  has_many :blocks, through: :block_contents
19
19
 
@@ -4,7 +4,7 @@ module Panda
4
4
  module CMS
5
5
  class Visit < ApplicationRecord
6
6
  belongs_to :page, class_name: "Panda::CMS::Page", foreign_key: :panda_cms_page_id, optional: true
7
- belongs_to :user, class_name: "Panda::CMS::User", foreign_key: :user_id, optional: true
7
+ belongs_to :user, class_name: "Panda::Core::User", foreign_key: :user_id, optional: true
8
8
  belongs_to :redirect, class_name: "Panda::CMS::Redirect", foreign_key: :redirect_id, optional: true
9
9
  end
10
10
  end
@@ -25,7 +25,7 @@
25
25
  <div class="py-3 px-4 mb-4 bg-black">
26
26
  <div class="flex justify-between items-center">
27
27
  <h2 class="text-base font-semibold leading-6 text-white" id="slideover-title"><i class="mr-2 fa-light fa-gear"></i> <%= yield :sidebar_title %> </h2>
28
- <a href="#" data-action="click->toggle#toggle touch->toggle#toggle"><i class="font-bold text-white fa-regular fa-xmark right"></i></a>
28
+ <button type="button" data-action="click->toggle#toggle touch->toggle#toggle"><i class="font-bold text-white fa-regular fa-xmark right"></i></button>
29
29
  </div>
30
30
  </div>
31
31
  <div class="flex flex-col flex-1 justify-between">