panda-core 0.2.3 → 0.4.1
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.
- checksums.yaml +4 -4
- data/README.md +185 -0
- data/app/assets/tailwind/application.css +279 -0
- data/app/assets/tailwind/tailwind.config.js +21 -0
- data/app/components/panda/core/UI/badge.rb +107 -0
- data/app/components/panda/core/UI/button.rb +89 -0
- data/app/components/panda/core/UI/card.rb +88 -0
- data/app/components/panda/core/admin/button_component.rb +46 -28
- data/app/components/panda/core/admin/container_component.rb +52 -4
- data/app/components/panda/core/admin/flash_message_component.rb +74 -9
- data/app/components/panda/core/admin/form_error_component.rb +48 -0
- data/app/components/panda/core/admin/form_input_component.rb +50 -0
- data/app/components/panda/core/admin/form_select_component.rb +68 -0
- data/app/components/panda/core/admin/heading_component.rb +52 -24
- data/app/components/panda/core/admin/panel_component.rb +33 -4
- data/app/components/panda/core/admin/slideover_component.rb +8 -4
- data/app/components/panda/core/admin/statistics_component.rb +19 -0
- data/app/components/panda/core/admin/tab_bar_component.rb +101 -0
- data/app/components/panda/core/admin/table_component.rb +90 -9
- data/app/components/panda/core/admin/tag_component.rb +21 -16
- data/app/components/panda/core/admin/user_activity_component.rb +43 -0
- data/app/components/panda/core/admin/user_display_component.rb +78 -0
- data/app/components/panda/core/base.rb +122 -0
- data/app/controllers/panda/core/admin/base_controller.rb +68 -0
- data/app/controllers/panda/core/admin/dashboard_controller.rb +7 -6
- data/app/controllers/panda/core/admin/my_profile_controller.rb +3 -3
- data/app/controllers/panda/core/admin/sessions_controller.rb +26 -5
- data/app/helpers/panda/core/sessions_helper.rb +21 -0
- data/app/javascript/panda/core/application.js +1 -0
- data/app/javascript/panda/core/vendor/@hotwired--stimulus.js +4 -0
- data/app/javascript/panda/core/vendor/@hotwired--turbo.js +160 -0
- data/app/javascript/panda/core/vendor/@rails--actioncable--src.js +4 -0
- data/app/models/panda/core/user.rb +17 -13
- data/app/views/layouts/panda/core/admin.html.erb +40 -57
- data/app/views/layouts/panda/core/admin_simple.html.erb +5 -0
- data/app/views/panda/core/admin/dashboard/_default_content.html.erb +73 -0
- data/app/views/panda/core/admin/dashboard/show.html.erb +4 -10
- data/app/views/panda/core/admin/my_profile/edit.html.erb +13 -27
- data/app/views/panda/core/admin/sessions/new.html.erb +13 -12
- data/app/views/panda/core/admin/shared/_breadcrumbs.html.erb +27 -34
- data/app/views/panda/core/admin/shared/_flash.html.erb +4 -30
- data/app/views/panda/core/admin/shared/_sidebar.html.erb +36 -20
- data/app/views/panda/core/shared/_footer.html.erb +2 -0
- data/app/views/panda/core/shared/_header.html.erb +19 -0
- data/config/importmap.rb +15 -0
- data/config/initializers/panda_core.rb +37 -1
- data/config/routes.rb +7 -7
- data/db/migrate/20250810120000_add_current_theme_to_panda_core_users.rb +7 -0
- data/lib/generators/panda/core/install_generator.rb +3 -9
- data/lib/generators/panda/core/templates/README +25 -0
- data/lib/generators/panda/core/templates/initializer.rb +28 -0
- data/lib/panda/core/asset_loader.rb +23 -8
- data/lib/panda/core/configuration.rb +41 -9
- data/lib/panda/core/debug.rb +47 -0
- data/lib/panda/core/engine.rb +82 -8
- data/lib/panda/core/version.rb +1 -1
- data/lib/panda/core.rb +1 -0
- data/lib/tasks/assets.rake +58 -392
- data/lib/tasks/panda_core_tasks.rake +16 -0
- metadata +102 -14
- data/app/components/panda/core/admin/container_component.html.erb +0 -12
- data/app/components/panda/core/admin/flash_message_component.html.erb +0 -31
- data/app/components/panda/core/admin/panel_component.html.erb +0 -7
- data/app/components/panda/core/admin/slideover_component.html.erb +0 -9
- data/app/components/panda/core/admin/table_component.html.erb +0 -29
- data/app/controllers/panda/core/admin_controller.rb +0 -28
|
@@ -1,10 +1,46 @@
|
|
|
1
1
|
Panda::Core.configure do |config|
|
|
2
|
+
config.admin_path = "/admin"
|
|
3
|
+
|
|
4
|
+
config.login_page_title = "Panda Admin"
|
|
5
|
+
config.admin_title = "Panda Admin"
|
|
6
|
+
|
|
7
|
+
# Configure authentication providers
|
|
8
|
+
# Uncomment and configure the providers you want to use
|
|
9
|
+
# Don't forget to add the corresponding gems (e.g., omniauth-google-oauth2)
|
|
10
|
+
#
|
|
11
|
+
# config.authentication_providers = {
|
|
12
|
+
# google_oauth2: {
|
|
13
|
+
# enabled: true,
|
|
14
|
+
# name: "Google", # Display name for the button
|
|
15
|
+
# icon: "google", # FontAwesome icon name (optional, auto-detected if not specified)
|
|
16
|
+
# path_name: "google", # Optional: Override URL path (default uses strategy name)
|
|
17
|
+
# # e.g., "google" gives /admin/auth/google instead of /admin/auth/google_oauth2
|
|
18
|
+
# client_id: Rails.application.credentials.dig(:google, :client_id),
|
|
19
|
+
# client_secret: Rails.application.credentials.dig(:google, :client_secret),
|
|
20
|
+
# options: {
|
|
21
|
+
# scope: "email,profile",
|
|
22
|
+
# prompt: "select_account",
|
|
23
|
+
# hd: "yourdomain.com" # Specify your domain here if you want to restrict admin logins
|
|
24
|
+
# }
|
|
25
|
+
# }
|
|
26
|
+
# }
|
|
27
|
+
|
|
28
|
+
# Configure the session token cookie name
|
|
29
|
+
config.session_token_cookie = :panda_session
|
|
30
|
+
|
|
2
31
|
# Configure the user class for the application
|
|
3
|
-
|
|
32
|
+
config.user_class = "Panda::Core::User"
|
|
33
|
+
|
|
34
|
+
# Configure the user identity class for the application
|
|
35
|
+
config.user_identity_class = "Panda::Core::UserIdentity"
|
|
4
36
|
|
|
5
37
|
# Configure the storage provider (default: :active_storage)
|
|
6
38
|
# config.storage_provider = :active_storage
|
|
7
39
|
|
|
8
40
|
# Configure the cache store (default: :memory_store)
|
|
9
41
|
# config.cache_store = :memory_store
|
|
42
|
+
|
|
43
|
+
# Configure EditorJS tools (optional)
|
|
44
|
+
# config.editor_js_tools = []
|
|
45
|
+
# config.editor_js_tool_config = {}
|
|
10
46
|
end
|
data/config/routes.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
Panda::Core::Engine.routes.draw do
|
|
2
|
-
#
|
|
3
|
-
|
|
2
|
+
# Get admin_path from configuration
|
|
3
|
+
# Default to "/admin" if not yet configured
|
|
4
|
+
admin_path = (Panda::Core.config.admin_path || "/admin").delete_prefix("/")
|
|
4
5
|
|
|
5
6
|
scope path: admin_path, as: "admin" do
|
|
6
7
|
get "/login", to: "admin/sessions#new", as: :login
|
|
@@ -12,11 +13,10 @@ Panda::Core::Engine.routes.draw do
|
|
|
12
13
|
get "/auth/failure", to: "admin/sessions#failure", as: :auth_failure
|
|
13
14
|
delete "/logout", to: "admin/sessions#destroy", as: :logout
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
# Dashboard and admin routes - authentication handled by AdminController
|
|
17
|
+
get "/", to: "admin/dashboard#show", as: :root
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
end
|
|
19
|
+
# Profile management
|
|
20
|
+
resource :my_profile, only: %i[edit update], controller: "admin/my_profile", path: "my_profile"
|
|
21
21
|
end
|
|
22
22
|
end
|
|
@@ -23,7 +23,7 @@ module Panda
|
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
def create_initializer
|
|
26
|
-
template "initializer.rb", "config/initializers/
|
|
26
|
+
template "initializer.rb", "config/initializers/panda.rb"
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
def mount_engine
|
|
@@ -33,14 +33,8 @@ module Panda
|
|
|
33
33
|
route 'mount Panda::Core::Engine => "/"'
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
-
def
|
|
37
|
-
|
|
38
|
-
return unless options[:orm] == "active_record"
|
|
39
|
-
|
|
40
|
-
migrations_path = File.expand_path("../../../../db/migrate", __dir__)
|
|
41
|
-
Dir.glob("#{migrations_path}/*.rb").each do |migration|
|
|
42
|
-
migration_template migration, "db/migrate/#{File.basename(migration)}"
|
|
43
|
-
end
|
|
36
|
+
def show_readme
|
|
37
|
+
readme "README" if behavior == :invoke
|
|
44
38
|
end
|
|
45
39
|
end
|
|
46
40
|
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
===============================================================================
|
|
2
|
+
|
|
3
|
+
Panda Core has been installed!
|
|
4
|
+
|
|
5
|
+
Next steps:
|
|
6
|
+
|
|
7
|
+
1. Install and run migrations:
|
|
8
|
+
|
|
9
|
+
rails panda:core:install:migrations
|
|
10
|
+
rails db:migrate
|
|
11
|
+
|
|
12
|
+
2. Configure authentication providers in config/initializers/panda.rb
|
|
13
|
+
(Uncomment and configure the providers you want to use)
|
|
14
|
+
|
|
15
|
+
3. Add the required OAuth gems to your Gemfile:
|
|
16
|
+
|
|
17
|
+
gem 'omniauth-google-oauth2' # For Google authentication
|
|
18
|
+
gem 'omniauth-microsoft_graph' # For Microsoft authentication
|
|
19
|
+
gem 'omniauth-github' # For GitHub authentication
|
|
20
|
+
|
|
21
|
+
4. Configure your OAuth credentials in Rails credentials:
|
|
22
|
+
|
|
23
|
+
rails credentials:edit
|
|
24
|
+
|
|
25
|
+
===============================================================================
|
|
@@ -1,4 +1,28 @@
|
|
|
1
1
|
Panda::Core.configure do |config|
|
|
2
|
+
config.admin_path = "/admin"
|
|
3
|
+
|
|
4
|
+
config.login_page_title = "Panda Admin"
|
|
5
|
+
config.admin_title = "Panda Admin"
|
|
6
|
+
|
|
7
|
+
# Configure authentication providers
|
|
8
|
+
# Uncomment and configure the providers you want to use
|
|
9
|
+
# Don't forget to add the corresponding gems (e.g., omniauth-google-oauth2)
|
|
10
|
+
#
|
|
11
|
+
# config.authentication_providers = {
|
|
12
|
+
# google_oauth2: {
|
|
13
|
+
# enabled: true,
|
|
14
|
+
# name: "Google", # Display name for the button
|
|
15
|
+
# icon: "google", # FontAwesome icon name (optional, auto-detected if not specified)
|
|
16
|
+
# client_id: Rails.application.credentials.dig(:google, :client_id),
|
|
17
|
+
# client_secret: Rails.application.credentials.dig(:google, :client_secret),
|
|
18
|
+
# options: {
|
|
19
|
+
# scope: "email,profile",
|
|
20
|
+
# prompt: "select_account",
|
|
21
|
+
# hd: "yourdomain.com" # Specify your domain here if you want to restrict admin logins
|
|
22
|
+
# }
|
|
23
|
+
# }
|
|
24
|
+
# }
|
|
25
|
+
|
|
2
26
|
# Configure the session token cookie name
|
|
3
27
|
config.session_token_cookie = :panda_session
|
|
4
28
|
|
|
@@ -13,4 +37,8 @@ Panda::Core.configure do |config|
|
|
|
13
37
|
|
|
14
38
|
# Configure the cache store (default: :memory_store)
|
|
15
39
|
# config.cache_store = :memory_store
|
|
40
|
+
|
|
41
|
+
# Configure EditorJS tools (optional)
|
|
42
|
+
# config.editor_js_tools = []
|
|
43
|
+
# config.editor_js_tool_config = {}
|
|
16
44
|
end
|
|
@@ -105,9 +105,19 @@ module Panda
|
|
|
105
105
|
end
|
|
106
106
|
|
|
107
107
|
else
|
|
108
|
-
# Development mode - use importmap
|
|
108
|
+
# Development mode - use importmap for JS and static CSS
|
|
109
109
|
tags = []
|
|
110
110
|
tags << javascript_include_tag("panda/core/application", type: "module")
|
|
111
|
+
|
|
112
|
+
# Add CSS if available
|
|
113
|
+
css_path = development_css_url
|
|
114
|
+
if css_path
|
|
115
|
+
css_attrs = {
|
|
116
|
+
rel: "stylesheet",
|
|
117
|
+
href: css_path
|
|
118
|
+
}
|
|
119
|
+
tags << tag(:link, css_attrs)
|
|
120
|
+
end
|
|
111
121
|
end
|
|
112
122
|
tags.join("\n").html_safe
|
|
113
123
|
end
|
|
@@ -144,11 +154,16 @@ module Panda
|
|
|
144
154
|
end
|
|
145
155
|
|
|
146
156
|
def development_css_url
|
|
147
|
-
|
|
148
|
-
|
|
157
|
+
# Try versioned file first
|
|
149
158
|
version = asset_version
|
|
150
|
-
|
|
151
|
-
File.exist?(Rails.
|
|
159
|
+
versioned_file = "/panda-core-assets/panda-core-#{version}.css"
|
|
160
|
+
return versioned_file if File.exist?(Rails.public_path.join("panda-core-assets", "panda-core-#{version}.css"))
|
|
161
|
+
|
|
162
|
+
# Fall back to unversioned file (always available from engine's public directory)
|
|
163
|
+
unversioned_file = "/panda-core-assets/panda-core.css"
|
|
164
|
+
return unversioned_file if File.exist?(Panda::Core::Engine.root.join("public", "panda-core-assets", "panda-core.css"))
|
|
165
|
+
|
|
166
|
+
nil
|
|
152
167
|
end
|
|
153
168
|
|
|
154
169
|
def asset_version
|
|
@@ -193,9 +208,9 @@ module Panda
|
|
|
193
208
|
end.compact.join(" ")
|
|
194
209
|
|
|
195
210
|
if content || block_given?
|
|
196
|
-
"<#{name}#{
|
|
211
|
+
"<#{name}#{" #{attrs}" if attrs.present?}>#{content || (block_given? ? yield : "")}</#{name}>"
|
|
197
212
|
else
|
|
198
|
-
"<#{name}#{
|
|
213
|
+
"<#{name}#{" #{attrs}" if attrs.present?}><#{name}>"
|
|
199
214
|
end
|
|
200
215
|
end
|
|
201
216
|
|
|
@@ -208,7 +223,7 @@ module Panda
|
|
|
208
223
|
end
|
|
209
224
|
end.compact.join(" ")
|
|
210
225
|
|
|
211
|
-
"<#{name}#{
|
|
226
|
+
"<#{name}#{" #{attrs}" if attrs.present?} />"
|
|
212
227
|
end
|
|
213
228
|
|
|
214
229
|
def javascript_include_tag(source, options = {})
|
|
@@ -19,8 +19,10 @@ module Panda
|
|
|
19
19
|
:authorization_policy,
|
|
20
20
|
:additional_user_params,
|
|
21
21
|
:available_themes,
|
|
22
|
+
:default_theme,
|
|
22
23
|
:login_logo_path,
|
|
23
24
|
:login_page_title,
|
|
25
|
+
:admin_title,
|
|
24
26
|
:initial_admin_breadcrumb,
|
|
25
27
|
:dashboard_redirect_path
|
|
26
28
|
|
|
@@ -36,9 +38,35 @@ module Panda
|
|
|
36
38
|
@session_token_cookie = :panda_session
|
|
37
39
|
@authentication_providers = {}
|
|
38
40
|
@admin_path = "/admin"
|
|
41
|
+
@default_theme = "default"
|
|
39
42
|
|
|
40
|
-
# Hook system for extending admin UI
|
|
41
|
-
@admin_navigation_items = ->(user) {
|
|
43
|
+
# Hook system for extending admin UI with sensible defaults
|
|
44
|
+
@admin_navigation_items = ->(user) {
|
|
45
|
+
items = [
|
|
46
|
+
{
|
|
47
|
+
label: "Dashboard",
|
|
48
|
+
path: @admin_path,
|
|
49
|
+
icon: "fa-solid fa-house"
|
|
50
|
+
}
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
# Add CMS navigation if available
|
|
54
|
+
if defined?(Panda::CMS)
|
|
55
|
+
items << {
|
|
56
|
+
label: "Content",
|
|
57
|
+
path: "#{@admin_path}/cms",
|
|
58
|
+
icon: "fa-solid fa-file-lines"
|
|
59
|
+
}
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
items << {
|
|
63
|
+
label: "My Profile",
|
|
64
|
+
path: "#{@admin_path}/my_profile/edit",
|
|
65
|
+
icon: "fa-solid fa-user"
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
items
|
|
69
|
+
}
|
|
42
70
|
@admin_dashboard_widgets = ->(user) { [] }
|
|
43
71
|
@user_attributes = []
|
|
44
72
|
@user_associations = []
|
|
@@ -48,26 +76,30 @@ module Panda
|
|
|
48
76
|
@additional_user_params = []
|
|
49
77
|
@available_themes = [["Default", "default"], ["Sky", "sky"]]
|
|
50
78
|
@login_logo_path = nil
|
|
51
|
-
@login_page_title = "
|
|
79
|
+
@login_page_title = "Panda Admin"
|
|
80
|
+
@admin_title = "Panda Admin"
|
|
52
81
|
@initial_admin_breadcrumb = nil # Proc that returns [label, path]
|
|
53
82
|
@dashboard_redirect_path = nil # Path to redirect to after login (defaults to admin_root_path)
|
|
54
83
|
end
|
|
55
84
|
end
|
|
56
85
|
|
|
57
86
|
class << self
|
|
58
|
-
attr_writer :
|
|
87
|
+
attr_writer :config
|
|
59
88
|
|
|
60
|
-
def
|
|
61
|
-
@
|
|
89
|
+
def config
|
|
90
|
+
@config ||= Configuration.new
|
|
62
91
|
end
|
|
63
92
|
|
|
64
93
|
def configure
|
|
65
|
-
yield(
|
|
94
|
+
yield(config)
|
|
66
95
|
end
|
|
67
96
|
|
|
68
|
-
def
|
|
69
|
-
@
|
|
97
|
+
def reset_config!
|
|
98
|
+
@config = Configuration.new
|
|
70
99
|
end
|
|
100
|
+
|
|
101
|
+
# Alias for backward compatibility with test expectations
|
|
102
|
+
alias_method :reset_configuration!, :reset_config!
|
|
71
103
|
end
|
|
72
104
|
end
|
|
73
105
|
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Panda
|
|
4
|
+
module Core
|
|
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, prefix: "PANDA")
|
|
14
|
+
return unless enabled?
|
|
15
|
+
|
|
16
|
+
timestamp = Time.current.strftime("%Y-%m-%d %H:%M:%S")
|
|
17
|
+
puts "[#{prefix} DEBUG #{timestamp}] #{message}"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Log an object with pretty printing (using awesome_print if available)
|
|
21
|
+
def inspect(object, label: nil, prefix: "PANDA")
|
|
22
|
+
return unless enabled?
|
|
23
|
+
|
|
24
|
+
timestamp = Time.current.strftime("%Y-%m-%d %H:%M:%S")
|
|
25
|
+
header = label ? "#{label}: " : ""
|
|
26
|
+
|
|
27
|
+
puts "\n[#{prefix} DEBUG #{timestamp}] #{header}"
|
|
28
|
+
if defined?(AwesomePrint)
|
|
29
|
+
ap object
|
|
30
|
+
else
|
|
31
|
+
pp object
|
|
32
|
+
end
|
|
33
|
+
puts
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Enable HTTP debugging for Net::HTTP requests
|
|
37
|
+
def enable_http_debug!
|
|
38
|
+
return unless enabled? || ENV["DEBUG_HTTP"].to_s.downcase == "true"
|
|
39
|
+
|
|
40
|
+
require "net/http"
|
|
41
|
+
Net::HTTP.set_debug_output($stdout)
|
|
42
|
+
log("HTTP debugging enabled - all HTTP requests will be logged")
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
data/lib/panda/core/engine.rb
CHANGED
|
@@ -13,11 +13,24 @@ module Panda
|
|
|
13
13
|
config.eager_load_namespaces << Panda::Core::Engine
|
|
14
14
|
|
|
15
15
|
# Add engine's app directories to autoload paths
|
|
16
|
+
# Note: Only add the root directories, not nested subdirectories
|
|
17
|
+
# Zeitwerk will automatically discover nested modules from these roots
|
|
16
18
|
config.autoload_paths += Dir[root.join("app", "models")]
|
|
17
19
|
config.autoload_paths += Dir[root.join("app", "controllers")]
|
|
18
20
|
config.autoload_paths += Dir[root.join("app", "builders")]
|
|
19
21
|
config.autoload_paths += Dir[root.join("app", "components")]
|
|
20
22
|
|
|
23
|
+
# Make files in public available to the main app (e.g. /panda-core-assets/panda-logo.png)
|
|
24
|
+
config.app_middleware.use(
|
|
25
|
+
Rack::Static,
|
|
26
|
+
urls: ["/panda-core-assets"],
|
|
27
|
+
root: Panda::Core::Engine.root.join("public"),
|
|
28
|
+
header_rules: [
|
|
29
|
+
# Disable caching in development for instant CSS updates
|
|
30
|
+
[:all, {"Cache-Control" => Rails.env.development? ? "no-cache, no-store, must-revalidate" : "public, max-age=31536000"}]
|
|
31
|
+
]
|
|
32
|
+
)
|
|
33
|
+
|
|
21
34
|
config.generators do |g|
|
|
22
35
|
g.test_framework :rspec
|
|
23
36
|
g.fixture_replacement :factory_bot
|
|
@@ -32,34 +45,95 @@ module Panda
|
|
|
32
45
|
end
|
|
33
46
|
end
|
|
34
47
|
|
|
35
|
-
initializer "panda_core.
|
|
48
|
+
initializer "panda_core.config" do |app|
|
|
36
49
|
# Configuration is already initialized with defaults in Configuration class
|
|
37
50
|
end
|
|
38
51
|
|
|
52
|
+
# Add importmap paths from the engine
|
|
53
|
+
initializer "panda_core.importmap", before: "importmap" do |app|
|
|
54
|
+
if app.config.respond_to?(:importmap)
|
|
55
|
+
# Create a new array if frozen
|
|
56
|
+
app.config.importmap.paths = app.config.importmap.paths.dup if app.config.importmap.paths.frozen?
|
|
57
|
+
|
|
58
|
+
# Add our paths
|
|
59
|
+
app.config.importmap.paths << root.join("config/importmap.rb")
|
|
60
|
+
|
|
61
|
+
# Handle cache sweepers similarly
|
|
62
|
+
if app.config.importmap.cache_sweepers.frozen?
|
|
63
|
+
app.config.importmap.cache_sweepers = app.config.importmap.cache_sweepers.dup
|
|
64
|
+
end
|
|
65
|
+
app.config.importmap.cache_sweepers << root.join("app/javascript")
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
39
69
|
initializer "panda_core.omniauth" do |app|
|
|
40
70
|
# Mount OmniAuth at configurable admin path
|
|
41
71
|
app.middleware.use OmniAuth::Builder do
|
|
42
72
|
# Configure OmniAuth to use the configured admin path
|
|
43
73
|
configure do |config|
|
|
44
|
-
config.path_prefix = "#{Panda::Core.
|
|
45
|
-
#
|
|
46
|
-
|
|
74
|
+
config.path_prefix = "#{Panda::Core.config.admin_path}/auth"
|
|
75
|
+
# POST-only for CSRF protection (CVE-2015-9284)
|
|
76
|
+
# All login forms use POST via form_tag method: "post"
|
|
77
|
+
config.allowed_request_methods = [:post]
|
|
47
78
|
end
|
|
48
79
|
|
|
49
|
-
Panda::Core.
|
|
80
|
+
Panda::Core.config.authentication_providers.each do |provider_name, settings|
|
|
81
|
+
# Build provider options, allowing custom path name override
|
|
82
|
+
provider_options = settings[:options] || {}
|
|
83
|
+
|
|
84
|
+
# If path_name is specified, use it to override the default strategy name in URLs
|
|
85
|
+
if settings[:path_name].present?
|
|
86
|
+
provider_options = provider_options.merge(name: settings[:path_name])
|
|
87
|
+
end
|
|
88
|
+
|
|
50
89
|
case provider_name.to_s
|
|
51
90
|
when "microsoft_graph"
|
|
52
|
-
provider :microsoft_graph, settings[:client_id], settings[:client_secret],
|
|
91
|
+
provider :microsoft_graph, settings[:client_id], settings[:client_secret], provider_options
|
|
53
92
|
when "google_oauth2"
|
|
54
|
-
provider :google_oauth2, settings[:client_id], settings[:client_secret],
|
|
93
|
+
provider :google_oauth2, settings[:client_id], settings[:client_secret], provider_options
|
|
55
94
|
when "github"
|
|
56
|
-
provider :github, settings[:client_id], settings[:client_secret],
|
|
95
|
+
provider :github, settings[:client_id], settings[:client_secret], provider_options
|
|
57
96
|
when "developer"
|
|
58
97
|
provider :developer if Rails.env.development?
|
|
59
98
|
end
|
|
60
99
|
end
|
|
61
100
|
end
|
|
62
101
|
end
|
|
102
|
+
|
|
103
|
+
# Load Phlex base component after Rails application is initialized
|
|
104
|
+
# This ensures Rails.application.routes is available
|
|
105
|
+
initializer "panda_core.phlex_base", after: :load_config_initializers do
|
|
106
|
+
require "phlex"
|
|
107
|
+
require "phlex-rails"
|
|
108
|
+
require "literal"
|
|
109
|
+
require "tailwind_merge"
|
|
110
|
+
|
|
111
|
+
# Load the base component
|
|
112
|
+
require root.join("app/components/panda/core/base")
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Set up ViewComponent and Lookbook previews
|
|
116
|
+
initializer "panda_core.view_component" do |app|
|
|
117
|
+
app.config.view_component.preview_paths ||= []
|
|
118
|
+
app.config.view_component.preview_paths << root.join("spec/components/previews")
|
|
119
|
+
|
|
120
|
+
# Add preview directories to autoload paths in development
|
|
121
|
+
if Rails.env.development?
|
|
122
|
+
# Handle frozen autoload_paths array
|
|
123
|
+
if app.config.autoload_paths.frozen?
|
|
124
|
+
app.config.autoload_paths = app.config.autoload_paths.dup
|
|
125
|
+
end
|
|
126
|
+
app.config.autoload_paths << root.join("spec/components/previews")
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# Create AdminController alias after controllers are loaded
|
|
131
|
+
# This allows other gems to inherit from Panda::Core::AdminController
|
|
132
|
+
initializer "panda_core.admin_controller_alias", after: :load_config_initializers do
|
|
133
|
+
ActiveSupport.on_load(:action_controller_base) do
|
|
134
|
+
Panda::Core.const_set(:AdminController, Panda::Core::Admin::BaseController) unless Panda::Core.const_defined?(:AdminController)
|
|
135
|
+
end
|
|
136
|
+
end
|
|
63
137
|
end
|
|
64
138
|
end
|
|
65
139
|
end
|
data/lib/panda/core/version.rb
CHANGED