super_admin 0.2.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 +7 -0
- data/README.md +216 -0
- data/Rakefile +30 -0
- data/app/assets/stylesheets/super_admin/application.css +15 -0
- data/app/assets/stylesheets/super_admin/tailwind.css +1 -0
- data/app/assets/stylesheets/super_admin/tailwind.source.css +25 -0
- data/app/controllers/super_admin/application_controller.rb +89 -0
- data/app/controllers/super_admin/associations_controller.rb +136 -0
- data/app/controllers/super_admin/audit_logs_controller.rb +39 -0
- data/app/controllers/super_admin/base_controller.rb +133 -0
- data/app/controllers/super_admin/dashboard_controller.rb +29 -0
- data/app/controllers/super_admin/exports_controller.rb +109 -0
- data/app/controllers/super_admin/resources_controller.rb +201 -0
- data/app/dashboards/super_admin/base_dashboard.rb +200 -0
- data/app/errors/super_admin/configuration_error.rb +6 -0
- data/app/helpers/super_admin/application_helper.rb +84 -0
- data/app/helpers/super_admin/exports_helper.rb +16 -0
- data/app/helpers/super_admin/resources_helper.rb +204 -0
- data/app/helpers/super_admin/route_helper.rb +7 -0
- data/app/javascript/super_admin/application.js +263 -0
- data/app/jobs/super_admin/application_job.rb +4 -0
- data/app/jobs/super_admin/generate_super_admin_csv_export_job.rb +100 -0
- data/app/mailers/super_admin/application_mailer.rb +6 -0
- data/app/models/super_admin/application_record.rb +5 -0
- data/app/models/super_admin/audit_log.rb +35 -0
- data/app/models/super_admin/csv_export.rb +67 -0
- data/app/services/super_admin/auditing.rb +74 -0
- data/app/services/super_admin/authorization.rb +113 -0
- data/app/services/super_admin/authorization_adapters/base_adapter.rb +100 -0
- data/app/services/super_admin/authorization_adapters/default_adapter.rb +77 -0
- data/app/services/super_admin/authorization_adapters/proc_adapter.rb +65 -0
- data/app/services/super_admin/authorization_adapters/pundit_adapter.rb +81 -0
- data/app/services/super_admin/csv_export_creator.rb +45 -0
- data/app/services/super_admin/dashboard_registry.rb +90 -0
- data/app/services/super_admin/dashboard_resolver.rb +100 -0
- data/app/services/super_admin/filter_builder.rb +185 -0
- data/app/services/super_admin/form_builder.rb +59 -0
- data/app/services/super_admin/form_fields/array_field.rb +35 -0
- data/app/services/super_admin/form_fields/association_field.rb +146 -0
- data/app/services/super_admin/form_fields/base_field.rb +53 -0
- data/app/services/super_admin/form_fields/boolean_field.rb +29 -0
- data/app/services/super_admin/form_fields/date_field.rb +15 -0
- data/app/services/super_admin/form_fields/date_time_field.rb +15 -0
- data/app/services/super_admin/form_fields/enum_field.rb +27 -0
- data/app/services/super_admin/form_fields/factory.rb +102 -0
- data/app/services/super_admin/form_fields/nested_field.rb +120 -0
- data/app/services/super_admin/form_fields/number_field.rb +29 -0
- data/app/services/super_admin/form_fields/text_area_field.rb +19 -0
- data/app/services/super_admin/model_inspector.rb +182 -0
- data/app/services/super_admin/queries/base_query.rb +45 -0
- data/app/services/super_admin/queries/filter_query.rb +188 -0
- data/app/services/super_admin/queries/resource_scope_query.rb +74 -0
- data/app/services/super_admin/queries/search_query.rb +146 -0
- data/app/services/super_admin/queries/sort_query.rb +41 -0
- data/app/services/super_admin/resource_configuration.rb +63 -0
- data/app/services/super_admin/resource_exporter.rb +78 -0
- data/app/services/super_admin/resource_query.rb +40 -0
- data/app/services/super_admin/resources/association_inspector.rb +112 -0
- data/app/services/super_admin/resources/collection_presenter.rb +63 -0
- data/app/services/super_admin/resources/context.rb +63 -0
- data/app/services/super_admin/resources/filter_params.rb +29 -0
- data/app/services/super_admin/resources/permitted_attributes.rb +104 -0
- data/app/services/super_admin/resources/value_normalizer.rb +121 -0
- data/app/services/super_admin/sensitive_attributes.rb +166 -0
- data/app/views/layouts/super_admin.html.erb +74 -0
- data/app/views/super_admin/audit_logs/index.html.erb +143 -0
- data/app/views/super_admin/dashboard/index.html.erb +79 -0
- data/app/views/super_admin/exports/index.html.erb +84 -0
- data/app/views/super_admin/exports/show.html.erb +57 -0
- data/app/views/super_admin/resources/_form.html.erb +42 -0
- data/app/views/super_admin/resources/destroy.turbo_stream.erb +17 -0
- data/app/views/super_admin/resources/edit.html.erb +37 -0
- data/app/views/super_admin/resources/index.html.erb +189 -0
- data/app/views/super_admin/resources/new.html.erb +31 -0
- data/app/views/super_admin/resources/show.html.erb +106 -0
- data/app/views/super_admin/shared/_breadcrumbs.html.erb +12 -0
- data/app/views/super_admin/shared/_custom_styles.html.erb +132 -0
- data/app/views/super_admin/shared/_flash.html.erb +55 -0
- data/app/views/super_admin/shared/_form_field.html.erb +35 -0
- data/app/views/super_admin/shared/_navigation.html.erb +92 -0
- data/app/views/super_admin/shared/_nested_fields.html.erb +59 -0
- data/app/views/super_admin/shared/_nested_record_fields.html.erb +45 -0
- data/config/importmap.rb +4 -0
- data/config/initializers/rack_attack.rb +134 -0
- data/config/initializers/super_admin.rb +117 -0
- data/config/locales/super_admin.en.yml +197 -0
- data/config/locales/super_admin.fr.yml +197 -0
- data/config/routes.rb +22 -0
- data/lib/generators/super_admin/dashboard_generator.rb +50 -0
- data/lib/generators/super_admin/install_generator.rb +58 -0
- data/lib/generators/super_admin/templates/20240101000001_create_super_admin_audit_logs.rb +24 -0
- data/lib/generators/super_admin/templates/20240101000002_create_super_admin_csv_exports.rb +33 -0
- data/lib/generators/super_admin/templates/super_admin.rb +58 -0
- data/lib/super_admin/dashboard_creator.rb +256 -0
- data/lib/super_admin/engine.rb +53 -0
- data/lib/super_admin/install_task.rb +96 -0
- data/lib/super_admin/version.rb +3 -0
- data/lib/super_admin.rb +7 -0
- data/lib/tasks/super_admin_tasks.rake +38 -0
- metadata +239 -0
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
fr:
|
|
2
|
+
time:
|
|
3
|
+
formats:
|
|
4
|
+
long: "%d %B %Y %H:%M"
|
|
5
|
+
super_admin:
|
|
6
|
+
layout:
|
|
7
|
+
window_title: "SuperAdmin - %{page_title}"
|
|
8
|
+
default_page_title: "Administration"
|
|
9
|
+
footer: "SuperAdmin - %{year}"
|
|
10
|
+
flash:
|
|
11
|
+
access_denied: "Vous n'avez pas les droits d'accès à cette section."
|
|
12
|
+
navigation:
|
|
13
|
+
brand: "SuperAdmin"
|
|
14
|
+
return_to_app: "Retour à l'app"
|
|
15
|
+
dashboard: "Dashboard"
|
|
16
|
+
exports: "Exports CSV"
|
|
17
|
+
audit_logs: "Journal d'activité"
|
|
18
|
+
models_heading: "Modèles (%{count})"
|
|
19
|
+
dashboard:
|
|
20
|
+
index:
|
|
21
|
+
page_title: "Dashboard"
|
|
22
|
+
breadcrumb: "Dashboard"
|
|
23
|
+
heading: "Dashboard SuperAdmin"
|
|
24
|
+
intro: "Gestion complète de tous les modèles de l'application"
|
|
25
|
+
stats:
|
|
26
|
+
models_label: "Modèles disponibles"
|
|
27
|
+
records_label: "Total enregistrements"
|
|
28
|
+
users_label: "Utilisateurs"
|
|
29
|
+
table:
|
|
30
|
+
title: "Tous les modèles"
|
|
31
|
+
headers:
|
|
32
|
+
model: "Modèle"
|
|
33
|
+
table: "Table"
|
|
34
|
+
records: "Enregistrements"
|
|
35
|
+
actions: "Actions"
|
|
36
|
+
manage: "Gérer →"
|
|
37
|
+
resources:
|
|
38
|
+
shared:
|
|
39
|
+
search_placeholder: "Rechercher..."
|
|
40
|
+
search_button: "Rechercher"
|
|
41
|
+
reset_filters: "Réinitialiser"
|
|
42
|
+
advanced_filters: "Filtres avancés"
|
|
43
|
+
contains_placeholder: "Contient..."
|
|
44
|
+
boolean_options:
|
|
45
|
+
placeholder: "—"
|
|
46
|
+
yes: "Oui"
|
|
47
|
+
no: "Non"
|
|
48
|
+
min_placeholder: "Min"
|
|
49
|
+
max_placeholder: "Max"
|
|
50
|
+
clear_filters: "Effacer les filtres"
|
|
51
|
+
apply_filters: "Appliquer"
|
|
52
|
+
bulk:
|
|
53
|
+
selected_suffix: "sélectionné(s)"
|
|
54
|
+
action_placeholder: "Action de masse"
|
|
55
|
+
destroy_action: "Supprimer la sélection"
|
|
56
|
+
apply: "Appliquer"
|
|
57
|
+
confirm: "Confirmer l'action sélectionnée sur les éléments cochés ?"
|
|
58
|
+
select_all_label: "Sélectionner tous les éléments"
|
|
59
|
+
select_item_label: "Sélectionner l'élément %{id}"
|
|
60
|
+
nested:
|
|
61
|
+
collection_hint: "Les modifications seront enregistrées lors de la sauvegarde."
|
|
62
|
+
add: "Ajouter %{model}"
|
|
63
|
+
remove: "Supprimer"
|
|
64
|
+
remove_hint: "Cocher pour supprimer l'élément lors de l'enregistrement."
|
|
65
|
+
entry_existing: "%{model} #%{id}"
|
|
66
|
+
entry_new: "Nouvel(le) %{model}"
|
|
67
|
+
missing_association: "Association %{name} introuvable."
|
|
68
|
+
max_depth_exceeded: "Profondeur maximale de nesting atteinte (%{max} niveaux). Impossible d'imbriquer davantage."
|
|
69
|
+
index:
|
|
70
|
+
export_csv: "Exporter en CSV"
|
|
71
|
+
view_exports: "Voir les exports"
|
|
72
|
+
new: "Créer"
|
|
73
|
+
records_count:
|
|
74
|
+
zero: "%{total} enregistrement"
|
|
75
|
+
one: "%{total} enregistrement"
|
|
76
|
+
other: "%{total} enregistrements"
|
|
77
|
+
actions_header: "Actions"
|
|
78
|
+
view: "Voir"
|
|
79
|
+
edit: "Éditer"
|
|
80
|
+
delete: "Supprimer"
|
|
81
|
+
delete_confirm: "Êtes-vous sûr ?"
|
|
82
|
+
empty_state: "Aucun enregistrement ne correspond à votre recherche."
|
|
83
|
+
form:
|
|
84
|
+
error_heading:
|
|
85
|
+
one: "1 erreur a empêché la sauvegarde :"
|
|
86
|
+
other: "%{count} erreurs ont empêché la sauvegarde :"
|
|
87
|
+
cancel: "Annuler"
|
|
88
|
+
create: "Créer"
|
|
89
|
+
update: "Mettre à jour"
|
|
90
|
+
boolean_hint: "Cocher pour activer"
|
|
91
|
+
array_placeholder: "Saisissez une valeur par ligne ou séparez-les par des virgules"
|
|
92
|
+
association_limited: "Affichage des %{count} premiers résultats sur %{total} au total. Utilisez la recherche pour affiner."
|
|
93
|
+
new:
|
|
94
|
+
page_title: "Nouveau - %{model}"
|
|
95
|
+
breadcrumb: "Nouveau"
|
|
96
|
+
heading: "Créer %{model}"
|
|
97
|
+
edit:
|
|
98
|
+
page_title: "Éditer - %{model}"
|
|
99
|
+
breadcrumb: "Éditer"
|
|
100
|
+
heading: "Éditer %{model} #%{id}"
|
|
101
|
+
show:
|
|
102
|
+
page_title: "Détails - %{model}"
|
|
103
|
+
breadcrumb_id: "#%{id}"
|
|
104
|
+
heading: "%{model} #%{id}"
|
|
105
|
+
edit: "Éditer"
|
|
106
|
+
delete: "Supprimer"
|
|
107
|
+
delete_confirm: "Êtes-vous sûr de vouloir supprimer cet enregistrement ?"
|
|
108
|
+
attributes: "Attributs"
|
|
109
|
+
associations: "Associations"
|
|
110
|
+
association_count_html:
|
|
111
|
+
one: "%{number} enregistrement"
|
|
112
|
+
other: "%{number} enregistrements"
|
|
113
|
+
association_none: "Aucun"
|
|
114
|
+
association_error: "Erreur : %{message}"
|
|
115
|
+
created_at: "Créé le %{date}"
|
|
116
|
+
updated_at: "Modifié le %{date}"
|
|
117
|
+
flash:
|
|
118
|
+
create:
|
|
119
|
+
success: "%{model} créé avec succès."
|
|
120
|
+
update:
|
|
121
|
+
success: "%{model} modifié avec succès."
|
|
122
|
+
destroy:
|
|
123
|
+
success: "%{model} supprimé avec succès."
|
|
124
|
+
dependencies: "Impossible de supprimer : des enregistrements dépendent de cette ressource."
|
|
125
|
+
bulk:
|
|
126
|
+
success: "%{count} %{model} supprimé(s) avec succès."
|
|
127
|
+
selection_required: "Sélectionnez au moins un enregistrement."
|
|
128
|
+
unsupported_action: "Action de masse non supportée."
|
|
129
|
+
dependencies: "Impossible de supprimer certains enregistrements car ils possèdent des dépendances."
|
|
130
|
+
load_model_failed: "Modèle introuvable : %{resource}"
|
|
131
|
+
not_found: "%{model} introuvable."
|
|
132
|
+
exports:
|
|
133
|
+
index:
|
|
134
|
+
title: "Exports CSV"
|
|
135
|
+
breadcrumb: "Exports"
|
|
136
|
+
heading: "Exports CSV"
|
|
137
|
+
subtitle: "Suivez l'avancement des exports et téléchargez-les une fois prêts."
|
|
138
|
+
back_to_resources: "Retour au dashboard"
|
|
139
|
+
processing_hint: "Traitement en cours… Vous pouvez fermer cette page."
|
|
140
|
+
expiration_hint: "Disponible jusqu'au %{date}"
|
|
141
|
+
download: "Télécharger"
|
|
142
|
+
pending: "En attente"
|
|
143
|
+
delete: "Supprimer"
|
|
144
|
+
delete_confirm: "Êtes-vous sûr de vouloir supprimer cet export ?"
|
|
145
|
+
empty: "Aucun export généré pour le moment."
|
|
146
|
+
table:
|
|
147
|
+
headers:
|
|
148
|
+
created_at: "Créé le"
|
|
149
|
+
resource: "Ressource"
|
|
150
|
+
status: "Statut"
|
|
151
|
+
records: "Enregistrements"
|
|
152
|
+
actions: "Actions"
|
|
153
|
+
show:
|
|
154
|
+
title: "Export %{token}"
|
|
155
|
+
heading: "Export %{resource}"
|
|
156
|
+
download: "Télécharger le CSV"
|
|
157
|
+
created_at: "Créé le"
|
|
158
|
+
status: "Statut"
|
|
159
|
+
records: "Nombre d'enregistrements"
|
|
160
|
+
expires_at: "Expire le"
|
|
161
|
+
error: "Erreur"
|
|
162
|
+
status:
|
|
163
|
+
pending: "En attente"
|
|
164
|
+
processing: "Traitement"
|
|
165
|
+
ready: "Prêt"
|
|
166
|
+
failed: "Échec"
|
|
167
|
+
flash:
|
|
168
|
+
created: "Export en cours. Rafraîchissez la page des exports pour suivre l'avancement (token %{token})."
|
|
169
|
+
unavailable: "Le fichier n'est pas encore disponible."
|
|
170
|
+
expired: "Ce fichier a expiré et n'est plus téléchargeable."
|
|
171
|
+
not_found: "Export introuvable."
|
|
172
|
+
destroyed: "Export supprimé avec succès."
|
|
173
|
+
audit_logs:
|
|
174
|
+
title: "Journal d'activité"
|
|
175
|
+
subtitle: "Suivez toutes les actions administratives effectuées dans SuperAdmin."
|
|
176
|
+
table_title: "Activité récente"
|
|
177
|
+
unknown_user: "Utilisateur inconnu"
|
|
178
|
+
view_changes: "Voir les modifications"
|
|
179
|
+
filters:
|
|
180
|
+
search: "Rechercher"
|
|
181
|
+
all_actions: "Toutes les actions"
|
|
182
|
+
all_resources: "Toutes les ressources"
|
|
183
|
+
apply: "Filtrer"
|
|
184
|
+
headers:
|
|
185
|
+
performed_at: "Effectué le"
|
|
186
|
+
user: "Utilisateur"
|
|
187
|
+
resource: "Ressource"
|
|
188
|
+
action: "Action"
|
|
189
|
+
changes: "Modifications"
|
|
190
|
+
context: "Contexte"
|
|
191
|
+
empty: "Aucune activité enregistrée pour le moment."
|
|
192
|
+
missing_table: "Le journal d'activité est indisponible. Lancez les migrations SuperAdmin pour créer la table correspondante."
|
|
193
|
+
helpers:
|
|
194
|
+
resources:
|
|
195
|
+
empty_string: "(vide)"
|
|
196
|
+
actions:
|
|
197
|
+
close: "Fermer"
|
data/config/routes.rb
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
SuperAdmin::Engine.routes.draw do
|
|
2
|
+
root "dashboard#index"
|
|
3
|
+
|
|
4
|
+
resources :exports, only: %i[index show create destroy], param: :token do
|
|
5
|
+
member do
|
|
6
|
+
get :download
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
get "associations/search", to: "associations#search", as: :association_search
|
|
11
|
+
|
|
12
|
+
resources :audit_logs, only: [ :index ]
|
|
13
|
+
|
|
14
|
+
get ":resource", to: "resources#index", as: :resources
|
|
15
|
+
post ":resource/bulk", to: "resources#bulk", as: :bulk_action
|
|
16
|
+
get ":resource/new", to: "resources#new", as: :new_resource
|
|
17
|
+
post ":resource", to: "resources#create"
|
|
18
|
+
get ":resource/:id", to: "resources#show", as: :resource
|
|
19
|
+
get ":resource/:id/edit", to: "resources#edit", as: :edit_resource
|
|
20
|
+
patch ":resource/:id", to: "resources#update"
|
|
21
|
+
delete ":resource/:id", to: "resources#destroy"
|
|
22
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rails/generators/base"
|
|
4
|
+
require "super_admin/dashboard_creator"
|
|
5
|
+
|
|
6
|
+
module SuperAdmin
|
|
7
|
+
module Generators
|
|
8
|
+
# Generator for creating SuperAdmin dashboard files.
|
|
9
|
+
# Usage: rails generate super_admin:dashboard [ModelName]
|
|
10
|
+
class DashboardGenerator < Rails::Generators::Base
|
|
11
|
+
desc "Generates a SuperAdmin dashboard for a specific model or all models"
|
|
12
|
+
|
|
13
|
+
argument :model_name, type: :string, required: false,
|
|
14
|
+
desc: "Name of the model (optional, generates for all models if omitted)"
|
|
15
|
+
|
|
16
|
+
def generate_dashboards
|
|
17
|
+
# Wrap the Thor shell to provide a puts method
|
|
18
|
+
generator = self
|
|
19
|
+
stdout_wrapper = Object.new
|
|
20
|
+
stdout_wrapper.define_singleton_method(:puts) do |message = ""|
|
|
21
|
+
generator.say(message)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
result = SuperAdmin::DashboardCreator.call(
|
|
25
|
+
model_name: model_name,
|
|
26
|
+
stdout: stdout_wrapper
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
if result[:generated].empty? && result[:skipped].empty?
|
|
30
|
+
say "\nNo dashboards were created. Make sure you have ActiveRecord models in your application.", :yellow
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def display_next_steps
|
|
35
|
+
return if @_already_displayed_next_steps
|
|
36
|
+
|
|
37
|
+
say "\n"
|
|
38
|
+
say "Dashboard generation complete! 🎉", :green
|
|
39
|
+
say "\n"
|
|
40
|
+
say "Next steps:", :yellow
|
|
41
|
+
say " 1. Review generated dashboards in app/dashboards/super_admin/"
|
|
42
|
+
say " 2. Customize attributes and display logic as needed"
|
|
43
|
+
say " 3. Visit #{SuperAdmin::Engine.routes.url_helpers.root_path rescue '/admin'} to see your admin interface"
|
|
44
|
+
say "\n"
|
|
45
|
+
|
|
46
|
+
@_already_displayed_next_steps = true
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rails/generators/base"
|
|
4
|
+
|
|
5
|
+
module SuperAdmin
|
|
6
|
+
module Generators
|
|
7
|
+
# Generator for installing SuperAdmin in a Rails application.
|
|
8
|
+
# Usage: rails generate super_admin:install
|
|
9
|
+
class InstallGenerator < Rails::Generators::Base
|
|
10
|
+
source_root File.expand_path("templates", __dir__)
|
|
11
|
+
|
|
12
|
+
desc "Installs SuperAdmin initializer and migrations"
|
|
13
|
+
|
|
14
|
+
def copy_initializer_file
|
|
15
|
+
template "super_admin.rb", "config/initializers/super_admin.rb"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def copy_migrations
|
|
19
|
+
rails_path = File.join(destination_root, "bin/rails")
|
|
20
|
+
|
|
21
|
+
unless File.exist?(rails_path)
|
|
22
|
+
say_status :skip, "bin/rails not found; skipping migration installation", :yellow
|
|
23
|
+
return
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
in_root do
|
|
27
|
+
run("bin/rails super_admin:install:migrations")
|
|
28
|
+
end
|
|
29
|
+
rescue StandardError => error
|
|
30
|
+
say_status :warning, "Could not run super_admin:install:migrations (#{error.message})", :yellow
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def display_post_install_message
|
|
34
|
+
say "\n"
|
|
35
|
+
say "SuperAdmin has been installed! 🎉", :green
|
|
36
|
+
say "\n"
|
|
37
|
+
say "Next steps:", :yellow
|
|
38
|
+
say " 1. Run migrations:"
|
|
39
|
+
say " rails db:migrate"
|
|
40
|
+
say "\n"
|
|
41
|
+
say " 2. Mount the engine in config/routes.rb:"
|
|
42
|
+
say " mount SuperAdmin::Engine => '/super_admin'"
|
|
43
|
+
say "\n"
|
|
44
|
+
say " 3. Generate dashboards for your models:"
|
|
45
|
+
say " rails generate super_admin:dashboard # All models"
|
|
46
|
+
say " rails generate super_admin:dashboard User # Specific model"
|
|
47
|
+
say "\n"
|
|
48
|
+
say " 4. Configure authentication/authorization in:"
|
|
49
|
+
say " config/initializers/super_admin.rb"
|
|
50
|
+
say "\n"
|
|
51
|
+
say " 5. Start your server and visit /super_admin"
|
|
52
|
+
say "\n"
|
|
53
|
+
say "✨ Stimulus controllers are automatically registered - no manual setup needed!", :cyan
|
|
54
|
+
say "\n"
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class CreateSuperAdminAuditLogs < ActiveRecord::Migration[7.1]
|
|
4
|
+
def change
|
|
5
|
+
return if table_exists?(:super_admin_audit_logs)
|
|
6
|
+
|
|
7
|
+
create_table :super_admin_audit_logs do |t|
|
|
8
|
+
t.references :user, null: true, foreign_key: false, index: true
|
|
9
|
+
t.string :user_email
|
|
10
|
+
t.string :resource_type, null: false
|
|
11
|
+
t.string :resource_id
|
|
12
|
+
t.string :action, null: false
|
|
13
|
+
t.json :changes_snapshot, null: false, default: {}
|
|
14
|
+
t.json :context, null: false, default: {}
|
|
15
|
+
t.datetime :performed_at, null: false
|
|
16
|
+
|
|
17
|
+
t.timestamps
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
add_index :super_admin_audit_logs, :performed_at
|
|
21
|
+
add_index :super_admin_audit_logs, [ :resource_type, :resource_id ]
|
|
22
|
+
add_index :super_admin_audit_logs, :action
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class CreateSuperAdminCsvExports < ActiveRecord::Migration[7.1]
|
|
4
|
+
def change
|
|
5
|
+
return if table_exists?(:super_admin_csv_exports)
|
|
6
|
+
|
|
7
|
+
create_table :super_admin_csv_exports do |t|
|
|
8
|
+
t.references :user, null: false, foreign_key: false, index: true
|
|
9
|
+
t.string :resource_name, null: false
|
|
10
|
+
t.string :model_class_name, null: false
|
|
11
|
+
t.string :status, null: false, default: "pending"
|
|
12
|
+
t.json :filters, null: false, default: {}
|
|
13
|
+
t.string :search
|
|
14
|
+
t.string :sort
|
|
15
|
+
t.string :direction
|
|
16
|
+
t.json :selected_attributes, null: false, default: []
|
|
17
|
+
t.integer :records_count
|
|
18
|
+
t.string :error_message
|
|
19
|
+
t.datetime :started_at
|
|
20
|
+
t.datetime :completed_at
|
|
21
|
+
t.datetime :expires_at
|
|
22
|
+
t.string :token, null: false
|
|
23
|
+
|
|
24
|
+
t.timestamps
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
add_index :super_admin_csv_exports, :token, unique: true
|
|
28
|
+
add_index :super_admin_csv_exports, :status
|
|
29
|
+
add_index :super_admin_csv_exports, :resource_name
|
|
30
|
+
add_index :super_admin_csv_exports, :created_at
|
|
31
|
+
add_index :super_admin_csv_exports, :expires_at
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
SuperAdmin.configure do |config|
|
|
4
|
+
# Maximum depth for nested associations when displaying resources
|
|
5
|
+
# config.max_nested_depth = 2
|
|
6
|
+
|
|
7
|
+
# Limit for association select dropdowns
|
|
8
|
+
# config.association_select_limit = 10
|
|
9
|
+
|
|
10
|
+
# Pagination limit for associations lists
|
|
11
|
+
# config.association_pagination_limit = 20
|
|
12
|
+
|
|
13
|
+
# Enable or disable search in association selects
|
|
14
|
+
# config.enable_association_search = true
|
|
15
|
+
|
|
16
|
+
# Authentication
|
|
17
|
+
# Configure how to authenticate users accessing SuperAdmin
|
|
18
|
+
# config.authenticate_with = proc { authenticate_user! }
|
|
19
|
+
|
|
20
|
+
# Current user method
|
|
21
|
+
# Method to call to get the current user
|
|
22
|
+
# config.current_user_method = :current_user
|
|
23
|
+
|
|
24
|
+
# User class
|
|
25
|
+
# The class representing users in your application
|
|
26
|
+
# config.user_class = "User"
|
|
27
|
+
|
|
28
|
+
# Authorization
|
|
29
|
+
# Configure authorization adapter (:auto, :pundit, :cancancan, or :custom)
|
|
30
|
+
# config.authorization_adapter = :auto
|
|
31
|
+
|
|
32
|
+
# Custom authorization block (when using :custom adapter)
|
|
33
|
+
# config.authorize_with = proc { |controller|
|
|
34
|
+
# redirect_to main_app.root_path unless current_user&.admin?
|
|
35
|
+
# }
|
|
36
|
+
|
|
37
|
+
# What to do when authorization fails
|
|
38
|
+
# config.on_unauthorized = proc { |controller|
|
|
39
|
+
# redirect_to main_app.root_path, alert: "You are not authorized to access this page."
|
|
40
|
+
# }
|
|
41
|
+
|
|
42
|
+
# Super admin check
|
|
43
|
+
# Additional check to determine if current user is a super admin
|
|
44
|
+
# config.super_admin_check = proc { |user|
|
|
45
|
+
# user.has_role?(:super_admin)
|
|
46
|
+
# }
|
|
47
|
+
|
|
48
|
+
# Layout
|
|
49
|
+
# Layout to use for SuperAdmin views
|
|
50
|
+
# config.layout = "super_admin"
|
|
51
|
+
|
|
52
|
+
# Parent controller
|
|
53
|
+
# Controller from which SuperAdmin controllers inherit
|
|
54
|
+
# config.parent_controller = "::ApplicationController"
|
|
55
|
+
|
|
56
|
+
# Default locale
|
|
57
|
+
# config.default_locale = :en
|
|
58
|
+
end
|