rsb-admin 0.9.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 +7 -0
- data/LICENSE +15 -0
- data/README.md +83 -0
- data/Rakefile +25 -0
- data/app/assets/javascripts/rsb/admin/themes/modern.js +37 -0
- data/app/assets/stylesheets/rsb/admin/themes/default.css +1358 -0
- data/app/assets/stylesheets/rsb/admin/themes/modern.css +1370 -0
- data/app/controllers/concerns/rsb/admin/authorization.rb +21 -0
- data/app/controllers/rsb/admin/admin_controller.rb +138 -0
- data/app/controllers/rsb/admin/admin_users_controller.rb +110 -0
- data/app/controllers/rsb/admin/dashboard_controller.rb +76 -0
- data/app/controllers/rsb/admin/profile_controller.rb +146 -0
- data/app/controllers/rsb/admin/profile_sessions_controller.rb +45 -0
- data/app/controllers/rsb/admin/resources_controller.rb +386 -0
- data/app/controllers/rsb/admin/roles_controller.rb +99 -0
- data/app/controllers/rsb/admin/sessions_controller.rb +139 -0
- data/app/controllers/rsb/admin/settings_controller.rb +203 -0
- data/app/controllers/rsb/admin/two_factor_controller.rb +105 -0
- data/app/helpers/rsb/admin/authorization_helper.rb +49 -0
- data/app/helpers/rsb/admin/branding_helper.rb +38 -0
- data/app/helpers/rsb/admin/formatting_helper.rb +205 -0
- data/app/helpers/rsb/admin/i18n_helper.rb +148 -0
- data/app/helpers/rsb/admin/icons_helper.rb +55 -0
- data/app/helpers/rsb/admin/table_helper.rb +132 -0
- data/app/helpers/rsb/admin/theme_helper.rb +84 -0
- data/app/helpers/rsb/admin/url_helper.rb +109 -0
- data/app/mailers/rsb/admin/admin_mailer.rb +37 -0
- data/app/models/rsb/admin/admin_session.rb +109 -0
- data/app/models/rsb/admin/admin_user.rb +153 -0
- data/app/models/rsb/admin/application_record.rb +10 -0
- data/app/models/rsb/admin/role.rb +63 -0
- data/app/views/layouts/rsb/admin/application.html.erb +45 -0
- data/app/views/rsb/admin/admin_mailer/email_verification.html.erb +11 -0
- data/app/views/rsb/admin/admin_mailer/email_verification.text.erb +11 -0
- data/app/views/rsb/admin/admin_users/_form.html.erb +52 -0
- data/app/views/rsb/admin/admin_users/edit.html.erb +10 -0
- data/app/views/rsb/admin/admin_users/index.html.erb +77 -0
- data/app/views/rsb/admin/admin_users/new.html.erb +10 -0
- data/app/views/rsb/admin/admin_users/show.html.erb +85 -0
- data/app/views/rsb/admin/dashboard/index.html.erb +36 -0
- data/app/views/rsb/admin/profile/edit.html.erb +67 -0
- data/app/views/rsb/admin/profile/show.html.erb +155 -0
- data/app/views/rsb/admin/resources/_filters.html.erb +58 -0
- data/app/views/rsb/admin/resources/_form.html.erb +20 -0
- data/app/views/rsb/admin/resources/_pagination.html.erb +33 -0
- data/app/views/rsb/admin/resources/_table.html.erb +70 -0
- data/app/views/rsb/admin/resources/edit.html.erb +7 -0
- data/app/views/rsb/admin/resources/index.html.erb +49 -0
- data/app/views/rsb/admin/resources/new.html.erb +7 -0
- data/app/views/rsb/admin/resources/page.html.erb +9 -0
- data/app/views/rsb/admin/resources/show.html.erb +55 -0
- data/app/views/rsb/admin/roles/_form.html.erb +197 -0
- data/app/views/rsb/admin/roles/edit.html.erb +7 -0
- data/app/views/rsb/admin/roles/index.html.erb +71 -0
- data/app/views/rsb/admin/roles/new.html.erb +7 -0
- data/app/views/rsb/admin/roles/show.html.erb +99 -0
- data/app/views/rsb/admin/sessions/new.html.erb +31 -0
- data/app/views/rsb/admin/sessions/two_factor.html.erb +39 -0
- data/app/views/rsb/admin/settings/_field.html.erb +115 -0
- data/app/views/rsb/admin/settings/index.html.erb +61 -0
- data/app/views/rsb/admin/shared/_badge.html.erb +1 -0
- data/app/views/rsb/admin/shared/_breadcrumbs.html.erb +12 -0
- data/app/views/rsb/admin/shared/_empty_state.html.erb +4 -0
- data/app/views/rsb/admin/shared/_flash.html.erb +22 -0
- data/app/views/rsb/admin/shared/_header.html.erb +50 -0
- data/app/views/rsb/admin/shared/_page_tabs.html.erb +21 -0
- data/app/views/rsb/admin/shared/_sidebar.html.erb +99 -0
- data/app/views/rsb/admin/shared/disabled.html.erb +38 -0
- data/app/views/rsb/admin/shared/fields/_checkbox.html.erb +6 -0
- data/app/views/rsb/admin/shared/fields/_datetime.html.erb +10 -0
- data/app/views/rsb/admin/shared/fields/_email.html.erb +10 -0
- data/app/views/rsb/admin/shared/fields/_hidden.html.erb +1 -0
- data/app/views/rsb/admin/shared/fields/_json.html.erb +11 -0
- data/app/views/rsb/admin/shared/fields/_number.html.erb +10 -0
- data/app/views/rsb/admin/shared/fields/_password.html.erb +10 -0
- data/app/views/rsb/admin/shared/fields/_select.html.erb +12 -0
- data/app/views/rsb/admin/shared/fields/_text.html.erb +10 -0
- data/app/views/rsb/admin/shared/fields/_textarea.html.erb +10 -0
- data/app/views/rsb/admin/shared/forbidden.html.erb +22 -0
- data/app/views/rsb/admin/themes/modern/views/shared/_header.html.erb +77 -0
- data/app/views/rsb/admin/themes/modern/views/shared/_sidebar.html.erb +135 -0
- data/app/views/rsb/admin/two_factor/backup_codes.html.erb +48 -0
- data/app/views/rsb/admin/two_factor/new.html.erb +53 -0
- data/config/locales/en.yml +140 -0
- data/config/locales/seo.en.yml +21 -0
- data/config/routes.rb +59 -0
- data/db/migrate/20260208000003_create_rsb_admin_tables.rb +43 -0
- data/db/migrate/20260214000001_add_otp_fields_to_rsb_admin_admin_users.rb +9 -0
- data/lib/generators/rsb/admin/install/install_generator.rb +45 -0
- data/lib/generators/rsb/admin/install/templates/rsb_admin_seeds.rb +24 -0
- data/lib/generators/rsb/admin/theme/templates/theme.css.tt +66 -0
- data/lib/generators/rsb/admin/theme/theme_generator.rb +218 -0
- data/lib/generators/rsb/admin/views/views_generator.rb +262 -0
- data/lib/rsb/admin/breadcrumb_item.rb +26 -0
- data/lib/rsb/admin/category_registration.rb +177 -0
- data/lib/rsb/admin/column_definition.rb +89 -0
- data/lib/rsb/admin/configuration.rb +69 -0
- data/lib/rsb/admin/engine.rb +34 -0
- data/lib/rsb/admin/filter_definition.rb +129 -0
- data/lib/rsb/admin/form_field_definition.rb +96 -0
- data/lib/rsb/admin/icons.rb +95 -0
- data/lib/rsb/admin/page_registration.rb +140 -0
- data/lib/rsb/admin/registry.rb +109 -0
- data/lib/rsb/admin/resource_dsl_context.rb +139 -0
- data/lib/rsb/admin/resource_registration.rb +287 -0
- data/lib/rsb/admin/settings_schema.rb +60 -0
- data/lib/rsb/admin/test_kit/helpers.rb +316 -0
- data/lib/rsb/admin/test_kit/resource_test_case.rb +193 -0
- data/lib/rsb/admin/test_kit.rb +11 -0
- data/lib/rsb/admin/theme_definition.rb +46 -0
- data/lib/rsb/admin/themes/modern.rb +44 -0
- data/lib/rsb/admin/version.rb +9 -0
- data/lib/rsb/admin.rb +177 -0
- data/lib/tasks/rsb/admin_tasks.rake +23 -0
- metadata +227 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 3071fe9fb7627de15eb032d8ae6c15059f3131b3f1b659621a39e642a6222bdc
|
|
4
|
+
data.tar.gz: 9a80f870291efcc587c5c065e8daad3435e07ef3cf2fede88b2a5146f6a7fe91
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 04bcb5b79f9670a8037d46ad7de412c4c2dea86419ae707a51504971e6e70cede74005ee6db11d20d8339055cd1b03a022fe964b869e166420c5a0a2197caf95
|
|
7
|
+
data.tar.gz: be1e160d6579cfd6cb1c1a08e0ccb9d5adc30bc39cd16ca1a09df3b255896ed98d77caa1a97377b932ab9e6d49a82b29509622a680fc825d4b4068c8de13c125
|
data/LICENSE
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
Rails SaaS Builder (RSB)
|
|
2
|
+
Copyright (C) 2026 Aleksandr Marchenko
|
|
3
|
+
|
|
4
|
+
This program is free software: you can redistribute it and/or modify
|
|
5
|
+
it under the terms of the GNU Lesser General Public License as published by
|
|
6
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
7
|
+
(at your option) any later version.
|
|
8
|
+
|
|
9
|
+
This program is distributed in the hope that it will be useful,
|
|
10
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
GNU Lesser General Public License for more details.
|
|
13
|
+
|
|
14
|
+
You should have received a copy of the GNU Lesser General Public License
|
|
15
|
+
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
data/README.md
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# rsb-admin
|
|
2
|
+
|
|
3
|
+
Lightweight, registrable admin panel for Rails SaaS Builder. Features dynamic resource CRUD, role-based access control with granular permissions, settings management, multi-theme support, and optional two-factor authentication. Other gems register resources and pages lazily via `ActiveSupport.on_load(:rsb_admin)`.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
### As part of Rails SaaS Builder
|
|
8
|
+
|
|
9
|
+
```ruby
|
|
10
|
+
gem "rails-saas-builder"
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### Standalone
|
|
14
|
+
|
|
15
|
+
```ruby
|
|
16
|
+
gem "rsb-admin"
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Then run:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
bundle install
|
|
23
|
+
rails generate rsb_admin:install
|
|
24
|
+
rails db:migrate
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Key Features
|
|
28
|
+
|
|
29
|
+
- Dynamic resource registration with DSL (columns, filters, form fields)
|
|
30
|
+
- Role-based access control with per-resource, per-action permissions
|
|
31
|
+
- Settings management page (tabbed by category)
|
|
32
|
+
- Built-in themes: default and modern (dark/light)
|
|
33
|
+
- Admin user management with email verification
|
|
34
|
+
- Two-factor authentication (TOTP with backup codes)
|
|
35
|
+
- Session management and device tracking
|
|
36
|
+
- Breadcrumb navigation and pagination
|
|
37
|
+
- Test kit for extension developers
|
|
38
|
+
- Lazy resource registration via `on_load(:rsb_admin)` hooks
|
|
39
|
+
|
|
40
|
+
## Basic Usage
|
|
41
|
+
|
|
42
|
+
```ruby
|
|
43
|
+
# Register resources from another gem
|
|
44
|
+
ActiveSupport.on_load(:rsb_admin) do |registry|
|
|
45
|
+
registry.register_category "Content" do
|
|
46
|
+
resource Post, icon: "file-text", actions: [:index, :show, :edit, :update] do
|
|
47
|
+
column :title, sortable: true, link: true
|
|
48
|
+
column :status, formatter: :badge
|
|
49
|
+
filter :status, type: :select, options: %w[draft published]
|
|
50
|
+
form_field :title, type: :text, required: true
|
|
51
|
+
form_field :body, type: :textarea
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Configuration
|
|
58
|
+
|
|
59
|
+
```ruby
|
|
60
|
+
RSB::Admin.configure do |config|
|
|
61
|
+
config.app_name = "My SaaS Admin"
|
|
62
|
+
config.company_name = "Acme Inc"
|
|
63
|
+
config.theme = :modern
|
|
64
|
+
end
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Test Kit
|
|
68
|
+
|
|
69
|
+
```ruby
|
|
70
|
+
# In your integration tests
|
|
71
|
+
include RSB::Admin::TestKit::Helpers
|
|
72
|
+
|
|
73
|
+
admin = create_test_admin!(superadmin: true)
|
|
74
|
+
sign_in_admin(admin)
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Documentation
|
|
78
|
+
|
|
79
|
+
Part of [Rails SaaS Builder](../README.md). See the main README for the full picture.
|
|
80
|
+
|
|
81
|
+
## License
|
|
82
|
+
|
|
83
|
+
[LGPL-3.0](../LICENSE)
|
data/Rakefile
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'bundler/setup'
|
|
4
|
+
require 'fileutils'
|
|
5
|
+
require 'rake/testtask'
|
|
6
|
+
|
|
7
|
+
task :prepare_test_db do
|
|
8
|
+
ENV['RAILS_ENV'] = 'test'
|
|
9
|
+
db = File.expand_path('test/dummy/db/test.sqlite3', __dir__)
|
|
10
|
+
FileUtils.rm_f(db)
|
|
11
|
+
require_relative 'test/dummy/config/environment'
|
|
12
|
+
ActiveRecord::Migration.verbose = false
|
|
13
|
+
ActiveRecord::MigrationContext.new(Rails.application.paths['db/migrate'].to_a).migrate
|
|
14
|
+
schema = File.expand_path('test/dummy/db/schema.rb', __dir__)
|
|
15
|
+
File.open(schema, 'w') { |f| ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection_pool, f) }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
Rake::TestTask.new(:test) do |t|
|
|
19
|
+
t.libs << 'test'
|
|
20
|
+
t.pattern = 'test/**/*_test.rb'
|
|
21
|
+
t.verbose = false
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
task test: :prepare_test_db
|
|
25
|
+
task default: :test
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
(function() {
|
|
2
|
+
var STORAGE_KEY = 'rsb-admin-mode';
|
|
3
|
+
|
|
4
|
+
function getPreferred() {
|
|
5
|
+
var stored = localStorage.getItem(STORAGE_KEY);
|
|
6
|
+
if (stored) return stored;
|
|
7
|
+
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function apply(mode) {
|
|
11
|
+
document.documentElement.setAttribute('data-rsb-mode', mode);
|
|
12
|
+
localStorage.setItem(STORAGE_KEY, mode);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Apply on load (rule #17)
|
|
16
|
+
apply(getPreferred());
|
|
17
|
+
|
|
18
|
+
// Toggle function exposed globally for the button
|
|
19
|
+
window.rsbToggleMode = function() {
|
|
20
|
+
var current = document.documentElement.getAttribute('data-rsb-mode');
|
|
21
|
+
apply(current === 'dark' ? 'light' : 'dark');
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
// Sidebar section collapse/expand toggle
|
|
25
|
+
window.rsbToggleSection = function(id) {
|
|
26
|
+
var content = document.getElementById(id);
|
|
27
|
+
var chevron = document.getElementById(id + '-chevron');
|
|
28
|
+
if (!content) return;
|
|
29
|
+
if (content.classList.contains('hidden')) {
|
|
30
|
+
content.classList.remove('hidden');
|
|
31
|
+
if (chevron) chevron.classList.add('rotate-90');
|
|
32
|
+
} else {
|
|
33
|
+
content.classList.add('hidden');
|
|
34
|
+
if (chevron) chevron.classList.remove('rotate-90');
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
})();
|