panda-core 0.4.1 → 0.6.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.
- checksums.yaml +4 -4
- data/app/assets/tailwind/application.css +95 -0
- data/app/assets/tailwind/tailwind.config.js +8 -0
- data/app/components/panda/core/UI/button.rb +45 -24
- data/app/components/panda/core/admin/breadcrumb_component.rb +133 -0
- data/app/components/panda/core/admin/button_component.rb +1 -1
- data/app/components/panda/core/admin/container_component.rb +27 -4
- data/app/components/panda/core/admin/file_gallery_component.rb +157 -0
- data/app/components/panda/core/admin/flash_message_component.rb +54 -36
- data/app/components/panda/core/admin/heading_component.rb +8 -7
- data/app/components/panda/core/admin/page_header_component.rb +107 -0
- data/app/components/panda/core/admin/panel_component.rb +1 -1
- data/app/components/panda/core/admin/slideover_component.rb +62 -4
- data/app/components/panda/core/admin/table_component.rb +11 -11
- data/app/components/panda/core/admin/tag_component.rb +39 -2
- data/app/components/panda/core/admin/user_display_component.rb +4 -5
- data/app/controllers/panda/core/admin/my_profile_controller.rb +2 -2
- data/app/controllers/panda/core/admin/sessions_controller.rb +6 -2
- data/app/controllers/panda/core/admin/test_sessions_controller.rb +60 -0
- data/app/helpers/panda/core/asset_helper.rb +31 -5
- data/app/helpers/panda/core/sessions_helper.rb +26 -1
- data/app/javascript/panda/core/application.js +8 -1
- data/app/javascript/panda/core/controllers/alert_controller.js +38 -0
- data/app/javascript/panda/core/controllers/index.js +3 -3
- data/app/javascript/panda/core/controllers/toggle_controller.js +41 -0
- data/app/javascript/panda/core/tailwindplus-elements.js +31 -0
- data/app/models/panda/core/user.rb +49 -6
- data/app/services/panda/core/attach_avatar_service.rb +67 -0
- data/app/views/layouts/panda/core/admin_simple.html.erb +1 -0
- data/app/views/panda/core/admin/my_profile/edit.html.erb +26 -1
- data/app/views/panda/core/admin/sessions/new.html.erb +2 -3
- data/app/views/panda/core/admin/shared/_breadcrumbs.html.erb +3 -3
- data/app/views/panda/core/admin/shared/_sidebar.html.erb +17 -12
- data/config/importmap.rb +15 -7
- data/config/routes.rb +9 -0
- data/db/migrate/20250811120000_add_oauth_avatar_url_to_panda_core_users.rb +7 -0
- data/lib/panda/core/engine.rb +12 -3
- data/lib/panda/core/services/base_service.rb +19 -4
- data/lib/panda/core/version.rb +1 -1
- data/lib/panda/core.rb +1 -0
- data/lib/tasks/panda_core_users.rake +158 -0
- metadata +11 -1
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
namespace :panda do
|
|
4
|
+
namespace :core do
|
|
5
|
+
namespace :users do
|
|
6
|
+
desc "List all users with their admin status"
|
|
7
|
+
task list: :environment do
|
|
8
|
+
users = Panda::Core::User.all.order(:email)
|
|
9
|
+
|
|
10
|
+
if users.empty?
|
|
11
|
+
puts "No users found."
|
|
12
|
+
else
|
|
13
|
+
puts "\nUsers:"
|
|
14
|
+
puts "-" * 80
|
|
15
|
+
users.each do |user|
|
|
16
|
+
admin_badge = user.admin? ? "[ADMIN]" : ""
|
|
17
|
+
puts "#{user.email.ljust(40)} #{admin_badge}"
|
|
18
|
+
end
|
|
19
|
+
puts "-" * 80
|
|
20
|
+
puts "Total: #{users.count} (#{Panda::Core::User.admins.count} admins)"
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
desc "Grant admin privileges to a user by email (EMAIL=user@example.com)"
|
|
25
|
+
task grant_admin: :environment do
|
|
26
|
+
email = ENV["EMAIL"]
|
|
27
|
+
|
|
28
|
+
unless email
|
|
29
|
+
puts "Error: EMAIL parameter is required"
|
|
30
|
+
puts "Usage: rails panda:core:users:grant_admin EMAIL=user@example.com"
|
|
31
|
+
exit 1
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
user = Panda::Core::User.find_by(email: email.downcase)
|
|
35
|
+
|
|
36
|
+
unless user
|
|
37
|
+
puts "Error: User with email '#{email}' not found"
|
|
38
|
+
puts "\nExisting users:"
|
|
39
|
+
Panda::Core::User.all.each do |u|
|
|
40
|
+
puts " - #{u.email}"
|
|
41
|
+
end
|
|
42
|
+
exit 1
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
if user.admin?
|
|
46
|
+
puts "User '#{user.email}' is already an admin"
|
|
47
|
+
else
|
|
48
|
+
user.update!(is_admin: true)
|
|
49
|
+
puts "✓ Granted admin privileges to '#{user.email}'"
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
desc "Revoke admin privileges from a user by email (EMAIL=user@example.com)"
|
|
54
|
+
task revoke_admin: :environment do
|
|
55
|
+
email = ENV["EMAIL"]
|
|
56
|
+
|
|
57
|
+
unless email
|
|
58
|
+
puts "Error: EMAIL parameter is required"
|
|
59
|
+
puts "Usage: rails panda:core:users:revoke_admin EMAIL=user@example.com"
|
|
60
|
+
exit 1
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
user = Panda::Core::User.find_by(email: email.downcase)
|
|
64
|
+
|
|
65
|
+
unless user
|
|
66
|
+
puts "Error: User with email '#{email}' not found"
|
|
67
|
+
exit 1
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
if user.admin?
|
|
71
|
+
# Safety check: prevent revoking the last admin
|
|
72
|
+
if Panda::Core::User.admins.count == 1
|
|
73
|
+
puts "Error: Cannot revoke admin privileges from the last admin user"
|
|
74
|
+
puts "Please create another admin first"
|
|
75
|
+
exit 1
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
user.update!(is_admin: false)
|
|
79
|
+
puts "✓ Revoked admin privileges from '#{user.email}'"
|
|
80
|
+
else
|
|
81
|
+
puts "User '#{user.email}' is not an admin"
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
desc "Create a new admin user (EMAIL=user@example.com FIRSTNAME=John LASTNAME=Doe)"
|
|
86
|
+
task create_admin: :environment do
|
|
87
|
+
email = ENV["EMAIL"]
|
|
88
|
+
firstname = ENV["FIRSTNAME"] || "Admin"
|
|
89
|
+
lastname = ENV["LASTNAME"] || "User"
|
|
90
|
+
|
|
91
|
+
unless email
|
|
92
|
+
puts "Error: EMAIL parameter is required"
|
|
93
|
+
puts "Usage: rails panda:core:users:create_admin EMAIL=user@example.com FIRSTNAME=John LASTNAME=Doe"
|
|
94
|
+
exit 1
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
existing_user = Panda::Core::User.find_by(email: email.downcase)
|
|
98
|
+
|
|
99
|
+
if existing_user
|
|
100
|
+
puts "Error: User with email '#{email}' already exists"
|
|
101
|
+
if existing_user.admin?
|
|
102
|
+
puts "This user is already an admin"
|
|
103
|
+
else
|
|
104
|
+
puts "Use 'rails panda:core:users:grant_admin EMAIL=#{email}' to make them an admin"
|
|
105
|
+
end
|
|
106
|
+
exit 1
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Build attributes hash based on schema
|
|
110
|
+
attributes = {
|
|
111
|
+
email: email.downcase,
|
|
112
|
+
is_admin: true
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
# Add name attributes based on schema
|
|
116
|
+
if Panda::Core::User.column_names.include?("name")
|
|
117
|
+
attributes[:name] = "#{firstname} #{lastname}".strip
|
|
118
|
+
elsif Panda::Core::User.column_names.include?("firstname") && Panda::Core::User.column_names.include?("lastname")
|
|
119
|
+
attributes[:firstname] = firstname
|
|
120
|
+
attributes[:lastname] = lastname
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
user = Panda::Core::User.create!(attributes)
|
|
124
|
+
puts "✓ Created admin user '#{user.email}'"
|
|
125
|
+
puts " Name: #{user.name}" if user.respond_to?(:name)
|
|
126
|
+
puts " Admin: #{user.admin?}"
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
desc "Delete a user by email (EMAIL=user@example.com)"
|
|
130
|
+
task delete: :environment do
|
|
131
|
+
email = ENV["EMAIL"]
|
|
132
|
+
|
|
133
|
+
unless email
|
|
134
|
+
puts "Error: EMAIL parameter is required"
|
|
135
|
+
puts "Usage: rails panda:core:users:delete EMAIL=user@example.com"
|
|
136
|
+
exit 1
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
user = Panda::Core::User.find_by(email: email.downcase)
|
|
140
|
+
|
|
141
|
+
unless user
|
|
142
|
+
puts "Error: User with email '#{email}' not found"
|
|
143
|
+
exit 1
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# Safety check: prevent deleting the last admin
|
|
147
|
+
if user.admin? && Panda::Core::User.admins.count == 1
|
|
148
|
+
puts "Error: Cannot delete the last admin user"
|
|
149
|
+
puts "Please create another admin first"
|
|
150
|
+
exit 1
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
user.destroy!
|
|
154
|
+
puts "✓ Deleted user '#{email}'"
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: panda-core
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.6.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Otaina Limited
|
|
@@ -447,13 +447,16 @@ files:
|
|
|
447
447
|
- app/components/panda/core/UI/badge.rb
|
|
448
448
|
- app/components/panda/core/UI/button.rb
|
|
449
449
|
- app/components/panda/core/UI/card.rb
|
|
450
|
+
- app/components/panda/core/admin/breadcrumb_component.rb
|
|
450
451
|
- app/components/panda/core/admin/button_component.rb
|
|
451
452
|
- app/components/panda/core/admin/container_component.rb
|
|
453
|
+
- app/components/panda/core/admin/file_gallery_component.rb
|
|
452
454
|
- app/components/panda/core/admin/flash_message_component.rb
|
|
453
455
|
- app/components/panda/core/admin/form_error_component.rb
|
|
454
456
|
- app/components/panda/core/admin/form_input_component.rb
|
|
455
457
|
- app/components/panda/core/admin/form_select_component.rb
|
|
456
458
|
- app/components/panda/core/admin/heading_component.rb
|
|
459
|
+
- app/components/panda/core/admin/page_header_component.rb
|
|
457
460
|
- app/components/panda/core/admin/panel_component.rb
|
|
458
461
|
- app/components/panda/core/admin/slideover_component.rb
|
|
459
462
|
- app/components/panda/core/admin/statistics_component.rb
|
|
@@ -468,13 +471,17 @@ files:
|
|
|
468
471
|
- app/controllers/panda/core/admin/dashboard_controller.rb
|
|
469
472
|
- app/controllers/panda/core/admin/my_profile_controller.rb
|
|
470
473
|
- app/controllers/panda/core/admin/sessions_controller.rb
|
|
474
|
+
- app/controllers/panda/core/admin/test_sessions_controller.rb
|
|
471
475
|
- app/controllers/panda/core/application_controller.rb
|
|
472
476
|
- app/helpers/panda/core/asset_helper.rb
|
|
473
477
|
- app/helpers/panda/core/sessions_helper.rb
|
|
474
478
|
- app/javascript/panda/core/application.js
|
|
479
|
+
- app/javascript/panda/core/controllers/alert_controller.js
|
|
475
480
|
- app/javascript/panda/core/controllers/index.js
|
|
476
481
|
- app/javascript/panda/core/controllers/theme_form_controller.js
|
|
482
|
+
- app/javascript/panda/core/controllers/toggle_controller.js
|
|
477
483
|
- app/javascript/panda/core/tailwindcss-stimulus-components.js
|
|
484
|
+
- app/javascript/panda/core/tailwindplus-elements.js
|
|
478
485
|
- app/javascript/panda/core/vendor/@hotwired--stimulus.js
|
|
479
486
|
- app/javascript/panda/core/vendor/@hotwired--turbo.js
|
|
480
487
|
- app/javascript/panda/core/vendor/@rails--actioncable--src.js
|
|
@@ -482,6 +489,7 @@ files:
|
|
|
482
489
|
- app/models/panda/core/breadcrumb.rb
|
|
483
490
|
- app/models/panda/core/current.rb
|
|
484
491
|
- app/models/panda/core/user.rb
|
|
492
|
+
- app/services/panda/core/attach_avatar_service.rb
|
|
485
493
|
- app/views/layouts/panda/core/admin.html.erb
|
|
486
494
|
- app/views/layouts/panda/core/admin_simple.html.erb
|
|
487
495
|
- app/views/panda/core/admin/dashboard/_default_content.html.erb
|
|
@@ -499,6 +507,7 @@ files:
|
|
|
499
507
|
- config/routes.rb
|
|
500
508
|
- db/migrate/20250809000001_create_panda_core_users.rb
|
|
501
509
|
- db/migrate/20250810120000_add_current_theme_to_panda_core_users.rb
|
|
510
|
+
- db/migrate/20250811120000_add_oauth_avatar_url_to_panda_core_users.rb
|
|
502
511
|
- lib/generators/panda/core/authentication/templates/reek_spec.rb
|
|
503
512
|
- lib/generators/panda/core/dev_tools/USAGE
|
|
504
513
|
- lib/generators/panda/core/dev_tools/templates/lefthook.yml
|
|
@@ -532,6 +541,7 @@ files:
|
|
|
532
541
|
- lib/tasks/panda/core/migrations.rake
|
|
533
542
|
- lib/tasks/panda_core.rake
|
|
534
543
|
- lib/tasks/panda_core_tasks.rake
|
|
544
|
+
- lib/tasks/panda_core_users.rake
|
|
535
545
|
homepage: https://github.com/tastybamboo/panda-core
|
|
536
546
|
licenses:
|
|
537
547
|
- BSD-3-Clause
|