cccux 0.1.0 → 0.3.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/CHANGELOG.md +66 -0
- data/README.md +124 -112
- data/Rakefile +57 -4
- data/app/assets/stylesheets/cccux/application.css +96 -72
- data/app/controllers/cccux/ability_permissions_controller.rb +138 -33
- data/app/controllers/cccux/application_controller.rb +7 -0
- data/app/controllers/cccux/cccux_controller.rb +20 -10
- data/app/controllers/cccux/dashboard_controller.rb +203 -32
- data/app/controllers/cccux/role_abilities_controller.rb +70 -0
- data/app/controllers/cccux/roles_controller.rb +70 -81
- data/app/controllers/cccux/users_controller.rb +22 -7
- data/app/controllers/concerns/cccux/application_controller_concern.rb +6 -2
- data/app/helpers/cccux/authorization_helper.rb +29 -21
- data/app/models/cccux/ability.rb +83 -32
- data/app/models/cccux/ability_permission.rb +9 -0
- data/app/models/cccux/post.rb +5 -0
- data/app/models/cccux/role.rb +19 -1
- data/app/models/cccux/role_ability.rb +3 -0
- data/app/models/concerns/cccux/user_concern.rb +5 -2
- data/app/views/cccux/ability_permissions/new.html.erb +2 -2
- data/app/views/cccux/dashboard/model_discovery.html.erb +7 -2
- data/app/views/cccux/roles/_form.html.erb +24 -71
- data/app/views/cccux/roles/edit.html.erb +5 -5
- data/app/views/cccux/roles/index.html.erb +1 -8
- data/app/views/cccux/roles/new.html.erb +1 -3
- data/app/views/cccux/users/edit.html.erb +4 -4
- data/app/views/cccux/users/new.html.erb +30 -15
- data/app/views/layouts/cccux/admin.html.erb +1 -2
- data/app/views/shared/_footer.html.erb +1 -1
- data/config/routes.rb +7 -6
- data/lib/cccux/engine.rb +7 -6
- data/lib/cccux/version.rb +1 -1
- data/lib/cccux.rb +12 -0
- data/lib/tasks/cccux.rake +271 -159
- metadata +10 -22
|
@@ -292,11 +292,11 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
292
292
|
function getActionType(action) {
|
|
293
293
|
const crudActions = ['read', 'create', 'update', 'destroy'];
|
|
294
294
|
if (crudActions.includes(action)) {
|
|
295
|
-
return 'CRUD';
|
|
295
|
+
return ' (CRUD)';
|
|
296
296
|
} else if (action === 'manage') {
|
|
297
297
|
return 'ALL';
|
|
298
298
|
} else {
|
|
299
|
-
return '
|
|
299
|
+
return ' (Custom)';
|
|
300
300
|
}
|
|
301
301
|
}
|
|
302
302
|
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
<div style="margin-bottom: 2rem;">
|
|
2
2
|
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem;">
|
|
3
3
|
<h1 style="margin: 0; color: #495057;">Model Discovery & Permission Sync</h1>
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
<div style="display: flex; gap: 0.5rem;">
|
|
5
|
+
<%= link_to "🔄 Refresh", cccux.clear_model_cache_path,
|
|
6
|
+
method: :post,
|
|
7
|
+
style: "background-color: #17a2b8; color: white; padding: 0.5rem 1rem; text-decoration: none; border-radius: 4px;" %>
|
|
8
|
+
<%= link_to "← Back to Dashboard", cccux.root_path,
|
|
9
|
+
style: "background-color: #6c757d; color: white; padding: 0.5rem 1rem; text-decoration: none; border-radius: 4px;" %>
|
|
10
|
+
</div>
|
|
6
11
|
</div>
|
|
7
12
|
|
|
8
13
|
<div style="background-color: #e7f3ff; border: 1px solid #b8daff; padding: 1rem; border-radius: 4px; margin-bottom: 2rem;">
|
|
@@ -1,78 +1,31 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
<div
|
|
4
|
-
<
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
<%= form_with(model: role, local: true) do |form| %>
|
|
2
|
+
<% if role.errors.any? %>
|
|
3
|
+
<div id="error_explanation">
|
|
4
|
+
<h2><%= pluralize(role.errors.count, "error") %> prohibited this role from being saved:</h2>
|
|
5
|
+
<ul>
|
|
6
|
+
<% role.errors.each do |error| %>
|
|
7
|
+
<li><%= error.full_message %></li>
|
|
8
|
+
<% end %>
|
|
9
|
+
</ul>
|
|
8
10
|
</div>
|
|
9
|
-
|
|
10
|
-
<%= form_with model: [role], url: role.new_record? ? cccux.roles_path : cccux.role_path(role), local: false do |form| %>
|
|
11
|
-
<% if role.errors.any? %>
|
|
12
|
-
<div style="background-color: #f8d7da; border: 1px solid #721c24; padding: 1rem; margin-bottom: 1rem; border-radius: 4px;">
|
|
13
|
-
<h4 style="margin-top: 0; color: #721c24;"><%= pluralize(role.errors.count, "error") %> prohibited this role from being saved:</h4>
|
|
14
|
-
<ul style="margin-bottom: 0; color: #721c24;">
|
|
15
|
-
<% role.errors.full_messages.each do |message| %>
|
|
16
|
-
<li><%= message %></li>
|
|
17
|
-
<% end %>
|
|
18
|
-
</ul>
|
|
19
|
-
</div>
|
|
20
|
-
<% end %>
|
|
11
|
+
<% end %>
|
|
21
12
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
placeholder: "Enter role name (e.g., Manager, Support, etc.)" %>
|
|
27
|
-
</div>
|
|
28
|
-
|
|
29
|
-
<div style="margin-bottom: 1.5rem;">
|
|
30
|
-
<%= form.label :description, style: "display: block; margin-bottom: 0.5rem; font-weight: bold; color: #495057;" %>
|
|
31
|
-
<%= form.text_area :description, rows: 3,
|
|
32
|
-
style: "width: 100%; padding: 0.75rem; border: 1px solid #ced4da; border-radius: 4px; font-size: 1rem; resize: vertical;",
|
|
33
|
-
placeholder: "Describe what this role can do and its responsibilities..." %>
|
|
34
|
-
</div>
|
|
35
|
-
|
|
36
|
-
<div style="margin-bottom: 1.5rem;">
|
|
37
|
-
<label style="display: flex; align-items: center; cursor: pointer;">
|
|
38
|
-
<%= form.check_box :active, { checked: role.active.nil? ? true : role.active },
|
|
39
|
-
style: "margin-right: 0.5rem; transform: scale(1.2);" %>
|
|
40
|
-
<span style="font-weight: bold; color: #495057;">Active Role</span>
|
|
41
|
-
</label>
|
|
42
|
-
<small style="color: #6c757d; font-size: 0.9rem; margin-top: 0.25rem; display: block; margin-left: 1.5rem;">
|
|
43
|
-
Only active roles can be assigned to users. Inactive roles are hidden from user assignment forms.
|
|
44
|
-
</small>
|
|
45
|
-
</div>
|
|
13
|
+
<div class="field">
|
|
14
|
+
<%= form.label :name %>
|
|
15
|
+
<%= form.text_field :name %>
|
|
16
|
+
</div>
|
|
46
17
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
placeholder: "Enter priority (lower numbers = higher priority)",
|
|
52
|
-
min: 1,
|
|
53
|
-
value: role.priority || 50 %>
|
|
54
|
-
<small style="color: #6c757d; font-size: 0.9rem; margin-top: 0.25rem; display: block;">
|
|
55
|
-
Priority determines role hierarchy. Lower numbers = higher priority (e.g., Admin=1, Manager=10, User=50)
|
|
56
|
-
</small>
|
|
57
|
-
</div>
|
|
18
|
+
<div class="field">
|
|
19
|
+
<%= form.label :description %>
|
|
20
|
+
<%= form.text_area :description %>
|
|
21
|
+
</div>
|
|
58
22
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
After creating this role, you'll be able to assign specific permissions (read, create, update, destroy)
|
|
64
|
-
for each resource (Orders, Users, etc.) on the role's edit page.
|
|
65
|
-
</p>
|
|
66
|
-
</div>
|
|
67
|
-
<% end %>
|
|
23
|
+
<div class="field">
|
|
24
|
+
<%= form.label :priority %>
|
|
25
|
+
<%= form.number_field :priority %>
|
|
26
|
+
</div>
|
|
68
27
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
style: "background-color: #007bff; color: white; padding: 0.75rem 1.5rem; border: none; border-radius: 4px; cursor: pointer; font-size: 1rem;" %>
|
|
72
|
-
<%= link_to "Cancel", cccux.roles_path,
|
|
73
|
-
data: { turbo_frame: role.new_record? ? "new_role_form" : "role_#{role.id}" },
|
|
74
|
-
style: "color: #6c757d; text-decoration: none; padding: 0.75rem 1rem; font-size: 1rem;" %>
|
|
75
|
-
</div>
|
|
76
|
-
<% end %>
|
|
28
|
+
<div class="actions">
|
|
29
|
+
<%= form.submit %>
|
|
77
30
|
</div>
|
|
78
31
|
<% end %>
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 2rem;">
|
|
2
2
|
<h1>Edit Role: <%= @role.name %></h1>
|
|
3
3
|
<div>
|
|
4
|
-
<%= link_to "View Role",
|
|
4
|
+
<%= link_to "View Role", role_path(@role),
|
|
5
5
|
style: "background-color: #17a2b8; color: white; padding: 0.5rem 1rem; text-decoration: none; border-radius: 4px; margin-right: 0.5rem;" %>
|
|
6
|
-
<%= link_to "Back to Roles",
|
|
6
|
+
<%= link_to "Back to Roles", roles_path,
|
|
7
7
|
style: "background-color: #6c757d; color: white; padding: 0.5rem 1rem; text-decoration: none; border-radius: 4px;" %>
|
|
8
8
|
</div>
|
|
9
9
|
</div>
|
|
10
10
|
|
|
11
|
-
<%= form_with model: [@role], url:
|
|
11
|
+
<%= form_with model: [@role], url: role_path(@role), local: true, method: :patch do |form| %>
|
|
12
12
|
<% if @role.errors.any? %>
|
|
13
13
|
<div style="background-color: #f8d7da; border: 1px solid #721c24; padding: 1rem; margin-bottom: 2rem; border-radius: 4px;">
|
|
14
14
|
<h4><%= pluralize(@role.errors.count, "error") %> prohibited this role from being saved:</h4>
|
|
@@ -297,13 +297,13 @@
|
|
|
297
297
|
<div>
|
|
298
298
|
<%= form.submit "Update Role",
|
|
299
299
|
style: "background-color: #28a745; color: white; padding: 0.75rem 1.5rem; border: none; border-radius: 4px; cursor: pointer; font-size: 1rem; margin-right: 1rem;" %>
|
|
300
|
-
<%= link_to "Cancel",
|
|
300
|
+
<%= link_to "Cancel", role_path(@role),
|
|
301
301
|
style: "color: #6c757d; text-decoration: none; padding: 0.75rem 1rem; font-size: 1rem;" %>
|
|
302
302
|
</div>
|
|
303
303
|
|
|
304
304
|
<% unless @role.users.any? %>
|
|
305
305
|
<div>
|
|
306
|
-
<%= link_to "Delete Role",
|
|
306
|
+
<%= link_to "Delete Role", role_path(@role),
|
|
307
307
|
data: { "turbo-method": :delete, "turbo-confirm": "Are you sure? This action cannot be undone." },
|
|
308
308
|
style: "background-color: #dc3545; color: white; padding: 0.75rem 1.5rem; text-decoration: none; border-radius: 4px; font-size: 1rem;" %>
|
|
309
309
|
</div>
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 2rem;">
|
|
2
2
|
<h1>Role Management</h1>
|
|
3
3
|
<%= link_to "New Role", cccux.new_role_path,
|
|
4
|
-
data: { turbo_frame: "new_role_form" },
|
|
5
4
|
style: "background-color: #007bff; color: white; padding: 0.5rem 1rem; text-decoration: none; border-radius: 4px;" %>
|
|
6
5
|
</div>
|
|
7
6
|
|
|
@@ -19,16 +18,11 @@
|
|
|
19
18
|
<% end %>
|
|
20
19
|
</div>
|
|
21
20
|
|
|
22
|
-
<!-- New Role Form Area -->
|
|
23
|
-
<%= turbo_frame_tag "new_role_form" do %>
|
|
24
|
-
<!-- Form will load here when "New Role" is clicked -->
|
|
25
|
-
<% end %>
|
|
26
|
-
|
|
27
21
|
<!-- Roles List -->
|
|
28
22
|
<div style="margin-bottom: 1rem;">
|
|
29
23
|
<h3 style="color: #495057; margin-bottom: 0.5rem;">Role Hierarchy</h3>
|
|
30
24
|
<p style="color: #6c757d; font-size: 0.9rem; margin-bottom: 1.5rem;">
|
|
31
|
-
|
|
25
|
+
Roles are listed by priority. Higher positions = higher priority.
|
|
32
26
|
</p>
|
|
33
27
|
</div>
|
|
34
28
|
|
|
@@ -45,7 +39,6 @@
|
|
|
45
39
|
<h3>No roles found</h3>
|
|
46
40
|
<p>Create your first role to get started.</p>
|
|
47
41
|
<%= link_to "Create Role", cccux.new_role_path,
|
|
48
|
-
data: { turbo_frame: "new_role_form" },
|
|
49
42
|
style: "background-color: #007bff; color: white; padding: 0.5rem 1rem; text-decoration: none; border-radius: 4px;" %>
|
|
50
43
|
</div>
|
|
51
44
|
<% end %>
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 2rem;">
|
|
2
2
|
<h1>Edit User: <%= @user.email %></h1>
|
|
3
|
-
<%= link_to "← Back to User",
|
|
3
|
+
<%= link_to "← Back to User", user_path(@user),
|
|
4
4
|
style: "background-color: #6c757d; color: white; padding: 0.5rem 1rem; text-decoration: none; border-radius: 4px;" %>
|
|
5
5
|
</div>
|
|
6
6
|
|
|
7
|
-
<%= form_with model: [@user], url:
|
|
7
|
+
<%= form_with model: [@user], url: user_path(@user), method: :patch, local: true do |form| %>
|
|
8
8
|
<% if @user.errors.any? %>
|
|
9
9
|
<div style="background-color: #f8d7da; border: 1px solid #f5c6cb; color: #721c24; padding: 1rem; border-radius: 4px; margin-bottom: 2rem;">
|
|
10
10
|
<h4 style="margin-top: 0;">Please fix the following errors:</h4>
|
|
@@ -103,12 +103,12 @@
|
|
|
103
103
|
<div>
|
|
104
104
|
<%= form.submit "Update User",
|
|
105
105
|
style: "background-color: #28a745; color: white; padding: 0.75rem 1.5rem; border: none; border-radius: 4px; cursor: pointer; font-size: 1rem; margin-right: 1rem;" %>
|
|
106
|
-
<%= link_to "Cancel",
|
|
106
|
+
<%= link_to "Cancel", user_path(@user),
|
|
107
107
|
style: "color: #6c757d; text-decoration: none; padding: 0.75rem 1rem; font-size: 1rem;" %>
|
|
108
108
|
</div>
|
|
109
109
|
|
|
110
110
|
<div>
|
|
111
|
-
<%= link_to "Delete User",
|
|
111
|
+
<%= link_to "Delete User", user_path(@user),
|
|
112
112
|
data: { "turbo-method": :delete, "turbo-confirm": "Are you sure? This will permanently delete the user and all their role assignments." },
|
|
113
113
|
style: "background-color: #dc3545; color: white; padding: 0.75rem 1.5rem; text-decoration: none; border-radius: 4px; font-size: 1rem;" %>
|
|
114
114
|
</div>
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 2rem;">
|
|
2
2
|
<h1>Create New User</h1>
|
|
3
|
-
<%= link_to "← Back to Users",
|
|
3
|
+
<%= link_to "← Back to Users", users_path,
|
|
4
4
|
style: "background-color: #6c757d; color: white; padding: 0.5rem 1rem; text-decoration: none; border-radius: 4px;" %>
|
|
5
5
|
</div>
|
|
6
6
|
|
|
7
|
-
<%= form_with model: [@user], url:
|
|
7
|
+
<%= form_with model: [@user], url: users_path, local: true do |form| %>
|
|
8
8
|
<% if @user.errors.any? %>
|
|
9
9
|
<div style="background-color: #f8d7da; border: 1px solid #f5c6cb; color: #721c24; padding: 1rem; border-radius: 4px; margin-bottom: 2rem;">
|
|
10
10
|
<h4 style="margin-top: 0;">Please fix the following errors:</h4>
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
</div>
|
|
17
17
|
<% end %>
|
|
18
18
|
|
|
19
|
-
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 2rem;
|
|
19
|
+
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 2rem;">
|
|
20
20
|
<!-- User Information -->
|
|
21
21
|
<div style="background-color: white; border: 1px solid #dee2e6; border-radius: 8px; padding: 1.5rem;">
|
|
22
22
|
<h3 style="margin-top: 0; color: #495057;">User Information</h3>
|
|
@@ -31,7 +31,6 @@
|
|
|
31
31
|
<%= form.label :password, style: "display: block; margin-bottom: 0.5rem; font-weight: bold; color: #495057;" %>
|
|
32
32
|
<%= form.password_field :password,
|
|
33
33
|
style: "width: 100%; padding: 0.75rem; border: 1px solid #ced4da; border-radius: 4px; font-size: 1rem;" %>
|
|
34
|
-
<small style="color: #6c757d; font-size: 0.875rem;">Minimum 6 characters</small>
|
|
35
34
|
</div>
|
|
36
35
|
|
|
37
36
|
<div style="margin-bottom: 1.5rem;">
|
|
@@ -39,21 +38,32 @@
|
|
|
39
38
|
<%= form.password_field :password_confirmation,
|
|
40
39
|
style: "width: 100%; padding: 0.75rem; border: 1px solid #ced4da; border-radius: 4px; font-size: 1rem;" %>
|
|
41
40
|
</div>
|
|
41
|
+
|
|
42
|
+
<div style="margin-bottom: 1.5rem;">
|
|
43
|
+
<%= form.label :first_name, style: "display: block; margin-bottom: 0.5rem; font-weight: bold; color: #495057;" %>
|
|
44
|
+
<%= form.text_field :first_name,
|
|
45
|
+
style: "width: 100%; padding: 0.75rem; border: 1px solid #ced4da; border-radius: 4px; font-size: 1rem;" %>
|
|
46
|
+
</div>
|
|
47
|
+
|
|
48
|
+
<div style="margin-bottom: 1.5rem;">
|
|
49
|
+
<%= form.label :last_name, style: "display: block; margin-bottom: 0.5rem; font-weight: bold; color: #495057;" %>
|
|
50
|
+
<%= form.text_field :last_name,
|
|
51
|
+
style: "width: 100%; padding: 0.75rem; border: 1px solid #ced4da; border-radius: 4px; font-size: 1rem;" %>
|
|
52
|
+
</div>
|
|
42
53
|
</div>
|
|
43
54
|
|
|
44
55
|
<!-- Role Assignment -->
|
|
45
56
|
<div style="background-color: white; border: 1px solid #dee2e6; border-radius: 8px; padding: 1.5rem;">
|
|
46
57
|
<h3 style="margin-top: 0; color: #495057;">Role Assignment</h3>
|
|
47
58
|
|
|
48
|
-
<div style="background-color: #
|
|
49
|
-
<p style="margin: 0; color: #
|
|
50
|
-
<strong>Note:</strong> Users automatically receive the "Basic User" role
|
|
51
|
-
You can assign additional roles here.
|
|
59
|
+
<div style="background-color: #fff3cd; border: 1px solid #ffeaa7; padding: 1rem; border-radius: 4px; margin-bottom: 1rem;">
|
|
60
|
+
<p style="margin: 0; color: #856404; font-size: 0.9rem;">
|
|
61
|
+
<strong>Note:</strong> Users will automatically receive the "Basic User" role.
|
|
52
62
|
</p>
|
|
53
63
|
</div>
|
|
54
64
|
|
|
55
65
|
<% if @roles.any? %>
|
|
56
|
-
<div style="max-height:
|
|
66
|
+
<div style="max-height: 300px; overflow-y: auto; border: 1px solid #e9ecef; border-radius: 4px; padding: 0.5rem;">
|
|
57
67
|
<% @roles.each do |role| %>
|
|
58
68
|
<div style="padding: 0.5rem; border-bottom: 1px solid #f8f9fa; display: flex; align-items: center;">
|
|
59
69
|
<%= check_box_tag "user[role_ids][]", role.id, false,
|
|
@@ -68,6 +78,15 @@
|
|
|
68
78
|
</div>
|
|
69
79
|
<% end %>
|
|
70
80
|
</div>
|
|
81
|
+
|
|
82
|
+
<div style="margin-top: 1rem; padding: 1rem; background-color: #e7f3ff; border-radius: 4px;">
|
|
83
|
+
<h5 style="margin: 0 0 0.5rem 0; color: #004085;">Role Selection Tips:</h5>
|
|
84
|
+
<ul style="margin: 0; padding-left: 1.5rem; color: #004085; font-size: 0.9rem;">
|
|
85
|
+
<li>Check roles to assign them to this user</li>
|
|
86
|
+
<li>Users automatically keep their "Basic User" role</li>
|
|
87
|
+
<li>Role assignments can be modified later</li>
|
|
88
|
+
</ul>
|
|
89
|
+
</div>
|
|
71
90
|
<% else %>
|
|
72
91
|
<div style="text-align: center; padding: 2rem; color: #6c757d; font-style: italic;">
|
|
73
92
|
No roles available. Create roles first.
|
|
@@ -77,18 +96,14 @@
|
|
|
77
96
|
</div>
|
|
78
97
|
|
|
79
98
|
<!-- Form Actions -->
|
|
80
|
-
<div style="background-color: white; border: 1px solid #dee2e6; border-radius: 8px; padding: 1.5rem;">
|
|
99
|
+
<div style="background-color: white; border: 1px solid #dee2e6; border-radius: 8px; padding: 1.5rem; margin-top: 2rem;">
|
|
81
100
|
<div style="display: flex; justify-content: space-between; align-items: center;">
|
|
82
101
|
<div>
|
|
83
102
|
<%= form.submit "Create User",
|
|
84
103
|
style: "background-color: #28a745; color: white; padding: 0.75rem 1.5rem; border: none; border-radius: 4px; cursor: pointer; font-size: 1rem; margin-right: 1rem;" %>
|
|
85
|
-
<%= link_to "Cancel",
|
|
104
|
+
<%= link_to "Cancel", users_path,
|
|
86
105
|
style: "color: #6c757d; text-decoration: none; padding: 0.75rem 1rem; font-size: 1rem;" %>
|
|
87
106
|
</div>
|
|
88
|
-
|
|
89
|
-
<div style="color: #6c757d; font-size: 0.9rem;">
|
|
90
|
-
<em>User will receive login credentials and can change password after first login</em>
|
|
91
|
-
</div>
|
|
92
107
|
</div>
|
|
93
108
|
</div>
|
|
94
109
|
<% end %>
|
|
@@ -7,8 +7,7 @@
|
|
|
7
7
|
<%= csp_meta_tag %>
|
|
8
8
|
|
|
9
9
|
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
|
|
10
|
-
|
|
11
|
-
<%= javascript_importmap_tags %>
|
|
10
|
+
<%# Remove JavaScript for now to avoid asset pipeline issues in tests %>
|
|
12
11
|
|
|
13
12
|
<!-- Sortable.js for drag and drop -->
|
|
14
13
|
<script src="https://cdn.jsdelivr.net/npm/sortablejs@1.15.0/Sortable.min.js"></script>
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
<span class="user-info">
|
|
21
21
|
Welcome, <%= current_user.respond_to?(:first_name) ? current_user.first_name : current_user.email %>
|
|
22
22
|
</span>
|
|
23
|
-
<%=
|
|
23
|
+
<%= button_to "Logout", main_app.destroy_user_session_path, method: :delete, class: "footer-link auth-link", style: "background: none; border: none; color: #007bff; text-decoration: none; padding: 5px 10px; border-radius: 4px; transition: all 0.2s ease; font-weight: 500; cursor: pointer; font: inherit;" %>
|
|
24
24
|
<% else %>
|
|
25
25
|
<%= link_to "Login", main_app.new_user_session_path, class: "footer-link auth-link" %>
|
|
26
26
|
<%= link_to "Sign Up", main_app.new_user_registration_path, class: "footer-link auth-link" %>
|
data/config/routes.rb
CHANGED
|
@@ -2,12 +2,16 @@ Cccux::Engine.routes.draw do
|
|
|
2
2
|
# Devise authentication routes - use different path to avoid conflicts
|
|
3
3
|
# devise_for :users, class_name: 'Cccux::User', path: 'auth'
|
|
4
4
|
|
|
5
|
+
# Root route for the engine - goes to dashboard
|
|
5
6
|
root 'dashboard#index'
|
|
6
|
-
|
|
7
|
+
|
|
8
|
+
# Dashboard route (alias for root)
|
|
9
|
+
get '/dashboard', to: 'dashboard#index', as: :dashboard
|
|
7
10
|
|
|
8
11
|
# Model Discovery Routes
|
|
9
12
|
get 'model-discovery', to: 'dashboard#model_discovery', as: :model_discovery
|
|
10
13
|
post 'sync-permissions', to: 'dashboard#sync_permissions', as: :sync_permissions
|
|
14
|
+
post 'clear-model-cache', to: 'dashboard#clear_model_cache', as: :clear_model_cache
|
|
11
15
|
|
|
12
16
|
# Admin CRUD routes for user management
|
|
13
17
|
resources :users do
|
|
@@ -22,6 +26,7 @@ Cccux::Engine.routes.draw do
|
|
|
22
26
|
end
|
|
23
27
|
|
|
24
28
|
resources :roles do
|
|
29
|
+
resources :role_abilities, only: [:index, :create, :destroy]
|
|
25
30
|
member do
|
|
26
31
|
patch :toggle_active
|
|
27
32
|
get :permissions
|
|
@@ -52,11 +57,7 @@ Cccux::Engine.routes.draw do
|
|
|
52
57
|
end
|
|
53
58
|
end
|
|
54
59
|
|
|
55
|
-
|
|
56
|
-
collection do
|
|
57
|
-
get :search
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
+
|
|
60
61
|
|
|
61
62
|
# Catch-all route for any unmatched paths in CCCUX - redirect to home
|
|
62
63
|
match '*unmatched', to: 'dashboard#not_found', via: :all
|
data/lib/cccux/engine.rb
CHANGED
|
@@ -24,15 +24,16 @@ module Cccux
|
|
|
24
24
|
load 'tasks/cccux.rake'
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
-
# Configure assets for
|
|
27
|
+
# Configure assets for Propshaft (Rails 8 default)
|
|
28
28
|
initializer "cccux.assets" do |app|
|
|
29
|
-
#
|
|
30
|
-
app.config.assets.paths << root.join('app', 'assets', 'stylesheets')
|
|
31
|
-
app.config.assets.paths << root.join('app', 'assets', 'javascripts')
|
|
32
|
-
|
|
33
|
-
# For Propshaft, ensure engine assets are available
|
|
29
|
+
# For Propshaft, add the engine's asset directory to the load path
|
|
34
30
|
if defined?(Propshaft)
|
|
35
31
|
app.config.assets.paths << root.join('app', 'assets')
|
|
32
|
+
else
|
|
33
|
+
# Fallback for Sprockets if needed
|
|
34
|
+
app.config.assets.paths << root.join("app", "assets", "javascripts")
|
|
35
|
+
app.config.assets.paths << root.join("app", "assets", "stylesheets")
|
|
36
|
+
app.config.assets.paths << root.join("app", "assets", "images")
|
|
36
37
|
end
|
|
37
38
|
end
|
|
38
39
|
|
data/lib/cccux/version.rb
CHANGED
data/lib/cccux.rb
CHANGED
|
@@ -4,4 +4,16 @@ require "cancancan"
|
|
|
4
4
|
|
|
5
5
|
module Cccux
|
|
6
6
|
# Your code goes here...
|
|
7
|
+
|
|
8
|
+
# Clear model discovery cache to force refresh after new models are created
|
|
9
|
+
def self.model_discovery_cache_clear
|
|
10
|
+
# Clear any cached model lists
|
|
11
|
+
@detected_models_cache = nil
|
|
12
|
+
@module_table_patterns_cache = nil
|
|
13
|
+
|
|
14
|
+
# Force Rails to reload constants
|
|
15
|
+
Rails.application.eager_load! if Rails.application.config.eager_load
|
|
16
|
+
|
|
17
|
+
Rails.logger.info "🔄 CCCUX model discovery cache cleared"
|
|
18
|
+
end
|
|
7
19
|
end
|