lesli_shield 1.0.3 → 1.0.4
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/stylesheets/lesli_shield/confirmations.css +18732 -0
- data/app/assets/stylesheets/lesli_shield/passwords.css +2 -238
- data/app/assets/stylesheets/lesli_shield/registrations.css +2 -238
- data/app/assets/stylesheets/lesli_shield/sessions.css +2 -238
- data/app/controllers/lesli_shield/dashboards_controller.rb +1 -8
- data/app/controllers/lesli_shield/invites_controller.rb +80 -0
- data/app/controllers/lesli_shield/role/actions_controller.rb +32 -20
- data/app/controllers/lesli_shield/roles_controller.rb +16 -8
- data/app/controllers/lesli_shield/sessions_controller.rb +5 -8
- data/app/controllers/lesli_shield/user/roles_controller.rb +62 -0
- data/app/controllers/lesli_shield/users_controller.rb +57 -20
- data/app/controllers/users/confirmations_controller.rb +42 -8
- data/app/controllers/users/passwords_controller.rb +52 -37
- data/app/controllers/users/registrations_controller.rb +2 -8
- data/app/controllers/users/sessions_controller.rb +57 -50
- data/app/helpers/lesli_shield/invites_helper.rb +4 -0
- data/app/helpers/lesli_shield/user/roles_helper.rb +4 -0
- data/app/interfaces/lesli_shield/authorization_interface.rb +8 -2
- data/app/mailers/lesli_shield/devise_mailer.rb +98 -0
- data/app/mailers/lesli_shield/invitation.html.erb +23 -0
- data/app/models/concerns/lesli_shield/user_security.rb +222 -0
- data/app/models/lesli_shield/account.rb +1 -1
- data/app/models/lesli_shield/dashboard.rb +1 -4
- data/app/models/lesli_shield/invite.rb +24 -0
- data/{lib/vue/confirmations.js → app/models/lesli_shield/role/action.rb} +17 -10
- data/{db/migrate/v1/0801003010_create_lesli_shield_dashboards.rb → app/models/lesli_shield/role/privilege.rb} +5 -4
- data/app/models/lesli_shield/user/role.rb +8 -0
- data/app/models/lesli_shield/user/session.rb +80 -0
- data/app/services/lesli_shield/invite_service.rb +43 -0
- data/app/services/lesli_shield/role_action_service.rb +118 -0
- data/app/services/lesli_shield/role_privilege_service.rb +112 -0
- data/app/{operators/lesli_shield/user_registration_operator.rb → services/lesli_shield/user_registration_service.rb} +26 -29
- data/app/services/lesli_shield/user_session_service.rb +78 -0
- data/app/services/lesli_shield/user_validator_service.rb +221 -0
- data/app/views/devise/confirmations/show.html.erb +4 -6
- data/app/views/devise/passwords/edit.html.erb +1 -2
- data/app/views/devise/passwords/new.html.erb +1 -1
- data/app/views/devise/registrations/new.html.erb +5 -4
- data/app/views/devise/sessions/new.html.erb +3 -2
- data/app/views/devise/shared/_application-devise-simple.erb +59 -0
- data/app/views/devise/shared/_application-devise.html.erb +76 -0
- data/app/views/lesli_shield/dashboards/_component-calendar.html.erb +1 -0
- data/app/views/lesli_shield/dashboards/_component-chart-bar.html.erb +6 -0
- data/app/views/lesli_shield/dashboards/_component-chart-line.html.erb +8 -0
- data/app/views/lesli_shield/dashboards/_component-count.html.erb +1 -0
- data/app/views/lesli_shield/dashboards/_component-date.html.erb +1 -0
- data/app/views/lesli_shield/dashboards/_component-weather.html.erb +1 -0
- data/app/views/lesli_shield/invites/_form.html.erb +10 -0
- data/app/views/lesli_shield/invites/_invite.html.erb +2 -0
- data/app/views/lesli_shield/invites/edit.html.erb +12 -0
- data/app/views/lesli_shield/invites/index.html.erb +66 -0
- data/{db/migrate/v1/0801001710_create_lesli_shield_settings.rb → app/views/lesli_shield/invites/new.html.erb} +9 -10
- data/{lib/vue/apps/dashboards/components/engine-version.vue → app/views/lesli_shield/invites/show.html.erb} +26 -43
- data/app/views/lesli_shield/partials/_navigation.html.erb +2 -4
- data/app/views/lesli_shield/{roles/_form-privileges.html.erb → role/actions/_form.html.erb} +5 -30
- data/app/views/lesli_shield/role/actions/index.html.erb +14 -0
- data/app/views/lesli_shield/roles/index.html.erb +2 -6
- data/app/views/lesli_shield/roles/new.html.erb +0 -11
- data/app/views/lesli_shield/roles/show.html.erb +5 -8
- data/app/views/lesli_shield/user/roles/_form.html.erb +17 -0
- data/app/views/lesli_shield/user/roles/_role.html.erb +2 -0
- data/app/views/lesli_shield/user/roles/edit.html.erb +12 -0
- data/app/views/lesli_shield/user/roles/index.html.erb +16 -0
- data/app/views/lesli_shield/user/roles/new.html.erb +11 -0
- data/app/views/lesli_shield/user/roles/show.html.erb +10 -0
- data/app/views/lesli_shield/users/{_viewer-activities.html.erb → _activities-viewer.html.erb} +2 -4
- data/app/views/lesli_shield/users/_information-card.html.erb +3 -3
- data/app/views/lesli_shield/users/_management-privileges.html.erb +74 -0
- data/app/views/lesli_shield/users/_management-security.html.erb +5 -0
- data/app/views/lesli_shield/users/index.html.erb +3 -7
- data/app/views/lesli_shield/users/new.html.erb +5 -11
- data/app/views/lesli_shield/users/show.html.erb +7 -5
- data/config/initializers/devise.rb +305 -304
- data/config/locales/translations.en.yml +4 -1
- data/config/locales/translations.es.yml +4 -1
- data/config/locales/translations.it.yml +4 -1
- data/config/routes.rb +7 -8
- data/db/migrate/v1/0801100210_create_lesli_shield_role_actions.rb +48 -0
- data/db/migrate/v1/0801100410_create_lesli_shield_role_privileges.rb +45 -0
- data/db/migrate/v1/0801110110_create_lesli_shield_user_roles.rb +43 -0
- data/db/migrate/v1/0801111210_create_lesli_shield_user_sessions.rb +56 -0
- data/db/migrate/v1/0801120110_create_lesli_shield_invites.rb +49 -0
- data/lib/lesli_shield/router.rb +21 -0
- data/lib/lesli_shield/version.rb +2 -2
- data/lib/lesli_shield.rb +1 -1
- data/lib/scss/confirmations.scss +24 -24
- data/lib/tasks/lesli_shield_tasks.rake +1 -1
- data/readme.md +59 -20
- metadata +57 -33
- data/app/controllers/lesli_shield/dashboard/components_controller.rb +0 -60
- data/app/models/lesli_shield/dashboard/component.rb +0 -18
- data/app/views/lesli_shield/dashboards/edit.html.erb +0 -1
- data/app/views/lesli_shield/dashboards/index.html.erb +0 -9
- data/app/views/lesli_shield/dashboards/new.html.erb +0 -1
- data/app/views/lesli_shield/dashboards/show.html.erb +0 -1
- data/app/views/lesli_shield/roles/_session.html.erb +0 -2
- data/app/views/lesli_shield/roles/edit.html.erb +0 -12
- data/app/views/lesli_shield/roles/update.turbo_stream.erb +0 -3
- data/app/views/lesli_shield/users/update.turbo_stream.erb +0 -3
- data/lib/lesli_shield/routing.rb +0 -23
- data/lib/vue/application.js +0 -83
- data/lib/vue/apps/sessions/index.vue +0 -50
- data/lib/vue/passwords.js +0 -137
- data/lib/vue/registrations.js +0 -144
- data/lib/vue/sessions.js +0 -148
- data/lib/vue/stores/sessions.js +0 -43
- data/lib/vue/stores/translations.json +0 -162
- /data/app/views/lesli_shield/roles/{_form-information.html.erb → _form.html.erb} +0 -0
- /data/db/migrate/v1/{0801120310_create_lesli_shield_user_shortcuts.rb → 0801111010_create_lesli_shield_user_shortcuts.rb} +0 -0
- /data/db/migrate/v1/{0801120410_create_lesli_shield_user_tokens.rb → 0801111110_create_lesli_shield_user_tokens.rb} +0 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
<%#
|
|
2
|
+
|
|
3
|
+
Lesli
|
|
4
|
+
|
|
5
|
+
Copyright (c) 2025, Lesli Technologies, S. A.
|
|
6
|
+
|
|
7
|
+
This program is free software: you can redistribute it and/or modify
|
|
8
|
+
it under the terms of the GNU General Public License as published by
|
|
9
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
10
|
+
(at your option) any later version.
|
|
11
|
+
|
|
12
|
+
This program is distributed in the hope that it will be useful,
|
|
13
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15
|
+
GNU General Public License for more details.
|
|
16
|
+
|
|
17
|
+
You should have received a copy of the GNU General Public License
|
|
18
|
+
along with this program. If not, see http://www.gnu.org/licenses/.
|
|
19
|
+
|
|
20
|
+
Lesli · Ruby on Rails SaaS Development Framework.
|
|
21
|
+
|
|
22
|
+
Made with ♥ by LesliTech
|
|
23
|
+
Building a better future, one line of code at a time.
|
|
24
|
+
|
|
25
|
+
@contact hello@lesli.tech
|
|
26
|
+
@website https://www.lesli.tech
|
|
27
|
+
@license GPLv3 http://www.gnu.org/licenses/gpl-3.0.en.html
|
|
28
|
+
|
|
29
|
+
// · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
|
|
30
|
+
// ·
|
|
31
|
+
%>
|
|
32
|
+
|
|
33
|
+
<% title = defined?(title) ? title : "" %>
|
|
34
|
+
<% back_to_login = defined?(back_to_login) ? back_to_login : false %>
|
|
35
|
+
|
|
36
|
+
<main id="lesli-application" class="standard-auth-view">
|
|
37
|
+
<section class="columns is-gapless">
|
|
38
|
+
<div class="column login-form">
|
|
39
|
+
<div class="hero is-fullheight">
|
|
40
|
+
<% if back_to_login %>
|
|
41
|
+
<div class="hero-head pt-6 pl-6">
|
|
42
|
+
<%= link_to new_user_session_path, :class => "has-text-primary" do %>
|
|
43
|
+
<span class="icon-text">
|
|
44
|
+
<span class="icon ri-lg">
|
|
45
|
+
<i class="ri-arrow-left-s-line"></i>
|
|
46
|
+
</span>
|
|
47
|
+
<span>Back to Login</span>
|
|
48
|
+
</span>
|
|
49
|
+
<% end %>
|
|
50
|
+
</div>
|
|
51
|
+
<% end %>
|
|
52
|
+
<div class="hero-body is-flex-direction-column is-justify-content-center">
|
|
53
|
+
|
|
54
|
+
<%# Logo container %>
|
|
55
|
+
<div class="logo has-text-centered mb-6">
|
|
56
|
+
<%= image_tag(
|
|
57
|
+
"#{lesli_instance_code}/brand/app-auth.svg", # dynamic path to the instance main logo
|
|
58
|
+
:class => "#{lesli_instance_code}-logo mb-2", # dynamic class according to the instance
|
|
59
|
+
:alt => "Main logo")
|
|
60
|
+
%>
|
|
61
|
+
<h1 class="is-title is-size-3 has-text-primary">
|
|
62
|
+
<%#= I18n.t("core.users/sessions.view_text_welcome") %>
|
|
63
|
+
<%= title %>
|
|
64
|
+
</h1>
|
|
65
|
+
</div>
|
|
66
|
+
|
|
67
|
+
<%= yield %>
|
|
68
|
+
|
|
69
|
+
</div>
|
|
70
|
+
<%# footer %>
|
|
71
|
+
<%#= render partial: "devise/shared/footer" %>
|
|
72
|
+
</div>
|
|
73
|
+
</div>
|
|
74
|
+
<div class="column background is-hidden-touch"></div>
|
|
75
|
+
</section>
|
|
76
|
+
</main>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%= render(LesliView::Widgets::Calendar.new) %>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%= render(LesliView::Widgets::Count.new('Total users today', rand(1...9999))) %>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%= render(LesliView::Widgets::Date.new) %>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%= render(LesliView::Widgets::Weather.new) %>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<%= form_with(model: @invite, builder: LesliView::Forms::Builder) do |form| %>
|
|
2
|
+
<%= form.fieldset do %>
|
|
3
|
+
<%= form.field_control_email(:email) %>
|
|
4
|
+
<%= form.field_control(:full_name) %>
|
|
5
|
+
<%= form.field_control(:telephone) %>
|
|
6
|
+
<%= form.field_control_textarea(:notes) %>
|
|
7
|
+
<hr/>
|
|
8
|
+
<%= form.field_control_submit %>
|
|
9
|
+
<% end %>
|
|
10
|
+
<% end %>
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
<%#
|
|
2
|
+
|
|
3
|
+
Lesli
|
|
4
|
+
|
|
5
|
+
Copyright (c) 2023, Lesli Technologies, S. A.
|
|
6
|
+
|
|
7
|
+
This program is free software: you can redistribute it and/or modify
|
|
8
|
+
it under the terms of the GNU General Public License as published by
|
|
9
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
10
|
+
(at your option) any later version.
|
|
11
|
+
|
|
12
|
+
This program is distributed in the hope that it will be useful,
|
|
13
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15
|
+
GNU General Public License for more details.
|
|
16
|
+
|
|
17
|
+
You should have received a copy of the GNU General Public License
|
|
18
|
+
along with this program. If not, see http://www.gnu.org/licenses/.
|
|
19
|
+
|
|
20
|
+
Lesli · Ruby on Rails SaaS Development Framework.
|
|
21
|
+
|
|
22
|
+
Made with ♥ by https://www.lesli.tech
|
|
23
|
+
Building a better future, one line of code at a time.
|
|
24
|
+
|
|
25
|
+
@contact hello@lesli.tech
|
|
26
|
+
@website https://www.lesli.tech
|
|
27
|
+
@license GPLv3 http://www.gnu.org/licenses/gpl-3.0.en.html
|
|
28
|
+
|
|
29
|
+
// · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
|
|
30
|
+
// ·
|
|
31
|
+
%>
|
|
32
|
+
<%
|
|
33
|
+
columns = [{
|
|
34
|
+
field: "id",
|
|
35
|
+
label: "ID",
|
|
36
|
+
sort: true
|
|
37
|
+
}, {
|
|
38
|
+
field: "full_name",
|
|
39
|
+
label: "Name",
|
|
40
|
+
sort: true
|
|
41
|
+
}, {
|
|
42
|
+
field: "email",
|
|
43
|
+
label: "Email",
|
|
44
|
+
sort: true
|
|
45
|
+
}, {
|
|
46
|
+
field: "telephone",
|
|
47
|
+
label: "Telephone",
|
|
48
|
+
sort: true
|
|
49
|
+
}, {
|
|
50
|
+
field: "status",
|
|
51
|
+
label: "status",
|
|
52
|
+
sort: true
|
|
53
|
+
}]
|
|
54
|
+
%>
|
|
55
|
+
<%= render LesliView::Layout::Container.new('shield-invites') do %>
|
|
56
|
+
<%= render LesliView::Components::Header.new('Invites') do %>
|
|
57
|
+
<%= render(LesliView::Elements::Button.new('Create invitation', url: new_invite_path, icon: "add", solid:true)) %>
|
|
58
|
+
<%= render(LesliView::Elements::Button.new(icon: 'refresh')) %>
|
|
59
|
+
<% end %>
|
|
60
|
+
<%= render LesliView::Components::Toolbar.new() %>
|
|
61
|
+
<%= render(LesliView::Elements::Table.new(
|
|
62
|
+
columns: columns,
|
|
63
|
+
records: @invites[:records],
|
|
64
|
+
link: lambda {|invite| invite_path(invite.id) }
|
|
65
|
+
)) %>
|
|
66
|
+
<% end %>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
<%#
|
|
2
2
|
|
|
3
3
|
Lesli
|
|
4
4
|
|
|
@@ -17,7 +17,7 @@ GNU General Public License for more details.
|
|
|
17
17
|
You should have received a copy of the GNU General Public License
|
|
18
18
|
along with this program. If not, see http://www.gnu.org/licenses/.
|
|
19
19
|
|
|
20
|
-
Lesli · Ruby on Rails Development
|
|
20
|
+
Lesli · Ruby on Rails SaaS Development Framework.
|
|
21
21
|
|
|
22
22
|
Made with ♥ by https://www.lesli.tech
|
|
23
23
|
Building a better future, one line of code at a time.
|
|
@@ -27,11 +27,10 @@ Building a better future, one line of code at a time.
|
|
|
27
27
|
@license GPLv3 http://www.gnu.org/licenses/gpl-3.0.en.html
|
|
28
28
|
|
|
29
29
|
// · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
|
|
30
|
-
// ·
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
end
|
|
30
|
+
// ·
|
|
31
|
+
%>
|
|
32
|
+
|
|
33
|
+
<%= render LesliView::Layout::Container.new('shield-invites') do %>
|
|
34
|
+
<%= render LesliView::Components::Header.new('Invites')%>
|
|
35
|
+
<%= render "form" %>
|
|
36
|
+
<% end %>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
<%#
|
|
2
|
+
|
|
3
3
|
Lesli
|
|
4
4
|
|
|
5
5
|
Copyright (c) 2023, Lesli Technologies, S. A.
|
|
@@ -28,44 +28,27 @@ Building a better future, one line of code at a time.
|
|
|
28
28
|
|
|
29
29
|
// · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
|
|
30
30
|
// ·
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
http.get(url.lesli("about")).then(result => {
|
|
56
|
-
lesliVersion.value = result.find(engine => engine.name == "Lesli")
|
|
57
|
-
}).catch(error => {
|
|
58
|
-
console.log(error)
|
|
59
|
-
})
|
|
60
|
-
})
|
|
61
|
-
</script>
|
|
62
|
-
<template>
|
|
63
|
-
<lesli-card>
|
|
64
|
-
<h6 class="title is-6 mb-2">
|
|
65
|
-
{{ lesliVersion.name }}
|
|
66
|
-
</h6>
|
|
67
|
-
<p class="p-0 m-0">version: {{ lesliVersion.version }}</p>
|
|
68
|
-
<p class="p-0 m-0">buid: {{ lesliVersion.build }}</p>
|
|
69
|
-
<p class="p-0 m-0">path: {{ lesliVersion.path }}</p>
|
|
70
|
-
</lesli-card>
|
|
71
|
-
</template>
|
|
31
|
+
%>
|
|
32
|
+
<%= render LesliView::Layout::Container.new('shield-invites') do %>
|
|
33
|
+
<%= render LesliView::Components::Header.new("Invite for #{ @invite.full_name.presence || @invite.email }") do %>
|
|
34
|
+
<%= render(LesliView::Elements::Button.new(
|
|
35
|
+
'Send invitation',
|
|
36
|
+
success:true,
|
|
37
|
+
solid:true,
|
|
38
|
+
icon:'send',
|
|
39
|
+
url: invite_path(@invite),
|
|
40
|
+
method: :put,
|
|
41
|
+
params: { invite: { status: :sent } }
|
|
42
|
+
)) %>
|
|
43
|
+
<%= render(LesliView::Elements::Button.new(
|
|
44
|
+
'Cancel invitation',
|
|
45
|
+
danger:true,
|
|
46
|
+
solid:true,
|
|
47
|
+
icon:'cancel',
|
|
48
|
+
url: invite_path(@invite),
|
|
49
|
+
method: :put,
|
|
50
|
+
params: { invite: { status: :cancelled } }
|
|
51
|
+
)) %>
|
|
52
|
+
<% end %>
|
|
53
|
+
<%= render "form" %>
|
|
54
|
+
<% end %>
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
=begin
|
|
1
|
+
<%#
|
|
3
2
|
|
|
4
3
|
Lesli
|
|
5
4
|
|
|
@@ -29,11 +28,10 @@ Building a better future, one line of code at a time.
|
|
|
29
28
|
|
|
30
29
|
// · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
|
|
31
30
|
// ·
|
|
32
|
-
=end
|
|
33
31
|
%>
|
|
34
32
|
|
|
35
33
|
<%= navigation_item(lesli_shield.dashboard_path, "Dashboard", "ri-dashboard-3-line"); %>
|
|
36
34
|
<%= navigation_item(lesli_shield.users_path, "Users", "ri-user-line"); %>
|
|
37
35
|
<%= navigation_item(lesli_shield.sessions_path, "Sessions", "ri-lock-line") %>
|
|
38
36
|
<%= navigation_item(lesli_shield.roles_path, "Roles", "ri-shield-user-line") %>
|
|
39
|
-
<%= navigation_item(lesli_shield.
|
|
37
|
+
<%= navigation_item(lesli_shield.invites_path, "Invites", "ri-user-add-line") %>
|
|
@@ -55,7 +55,8 @@ columns = [{
|
|
|
55
55
|
}
|
|
56
56
|
</style>
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
<section id="shield-role-actions-form">
|
|
59
|
+
<%= render(LesliView::Elements::Table.new(:columns => columns)) do |table| %>
|
|
59
60
|
<% @role_actions.each do |controller_name, actions| %>
|
|
60
61
|
<% table.with_row do |row| %>
|
|
61
62
|
<% row.with_cell do %>
|
|
@@ -65,9 +66,8 @@ columns = [{
|
|
|
65
66
|
<% row.with_cell do %>
|
|
66
67
|
<% if action %>
|
|
67
68
|
<%= button_to role_action_path(action),
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
form: { "x-data" => "toggleForm", "x-on:submit.prevent" => "submit($el)" } do %>
|
|
69
|
+
class: "mini-toggle #{'active' if action[:active] == 1}",
|
|
70
|
+
method: (action[:active] == 1 ? :delete : :patch) do %>
|
|
71
71
|
<span class="mini-toggle-slider"></span>
|
|
72
72
|
<% end %>
|
|
73
73
|
<% end %>
|
|
@@ -76,29 +76,4 @@ columns = [{
|
|
|
76
76
|
<% end %>
|
|
77
77
|
<% end %>
|
|
78
78
|
<% end %>
|
|
79
|
-
|
|
80
|
-
document.addEventListener('alpine:init', () => {
|
|
81
|
-
Alpine.data('toggleForm', () => ({
|
|
82
|
-
submit(form) {
|
|
83
|
-
const method = form.querySelector('input[name="_method"]')?.value?.toUpperCase() || form.method.toUpperCase();
|
|
84
|
-
fetch(form.action, {
|
|
85
|
-
method: method,
|
|
86
|
-
headers: {
|
|
87
|
-
'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').content,
|
|
88
|
-
'Accept': 'text/vnd.turbo-stream.html' // or 'application/json'
|
|
89
|
-
},
|
|
90
|
-
//body: new URLSearchParams(new FormData(form))
|
|
91
|
-
}).then(response => {
|
|
92
|
-
if (!response.ok) throw new Error("Request failed");
|
|
93
|
-
return response.text();
|
|
94
|
-
}).then(() => {
|
|
95
|
-
// Success! Toggle the class
|
|
96
|
-
form.querySelector('button')?.classList.toggle('active');
|
|
97
|
-
}).catch(err => {
|
|
98
|
-
console.error("Error:", err);
|
|
99
|
-
alert("Something went wrong");
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
}))
|
|
103
|
-
});
|
|
104
|
-
</script>
|
|
79
|
+
</section>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<%= render LesliView::Layout::Container.new("shield-role-actions") do %>
|
|
2
|
+
<%= render LesliView::Components::Header.new("#{@role.name} privileges", :back => role_path(@role)) do %>
|
|
3
|
+
<%= render(LesliView::Elements::Button.new('Deploy privileges',
|
|
4
|
+
solid:true,
|
|
5
|
+
danger:true,
|
|
6
|
+
icon: 'shield',
|
|
7
|
+
css_class: 'is-light is-hovered',
|
|
8
|
+
url: deploy_role_path(@role.id),
|
|
9
|
+
method: :post
|
|
10
|
+
|
|
11
|
+
)) %>
|
|
12
|
+
<% end %>
|
|
13
|
+
<%= render "form" %>
|
|
14
|
+
<% end %>
|
|
@@ -29,12 +29,8 @@ columns = [{
|
|
|
29
29
|
%>
|
|
30
30
|
<%= render LesliView::Layout::Container.new("shield-roles") do %>
|
|
31
31
|
<%= render LesliView::Components::Header.new("Roles") do %>
|
|
32
|
-
<%= render(LesliView::Elements::Button.new(icon: "add", solid:true))
|
|
33
|
-
|
|
34
|
-
<% end %>
|
|
35
|
-
<%= render(LesliView::Elements::Button.new(icon: "refresh")) do %>
|
|
36
|
-
Reload
|
|
37
|
-
<% end %>
|
|
32
|
+
<%= render(LesliView::Elements::Button.new('Add new', icon: "add", solid:true)) %>
|
|
33
|
+
<%= render(LesliView::Elements::Button.new('Reload', icon: "refresh")) %>
|
|
38
34
|
<% end %>
|
|
39
35
|
<%= render LesliView::Components::Toolbar.new() %>
|
|
40
36
|
<%= render(LesliView::Elements::Table.new(
|
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
<%= render LesliView::Layout::Container.new("shield-roles-show") do %>
|
|
2
2
|
<%= render LesliView::Components::Header.new(@role.name) do %>
|
|
3
|
+
<%= render(LesliView::Elements::Button.new('Privileges',
|
|
4
|
+
url: role_actions_path(@role),
|
|
5
|
+
icon: 'security'
|
|
6
|
+
)) %>
|
|
3
7
|
<% end %>
|
|
4
8
|
|
|
5
|
-
<%= render
|
|
6
|
-
<% tabs.with_tab(title:"privileges", icon:"security") do %>
|
|
7
|
-
<%= render "form-privileges" %>
|
|
8
|
-
<% end %>
|
|
9
|
-
<% tabs.with_tab(title:"information", icon:"info_outline") do %>
|
|
10
|
-
<%= render "form-information" %>
|
|
11
|
-
<% end %>
|
|
12
|
-
<% end %>
|
|
9
|
+
<%= render "form" %>
|
|
13
10
|
<% end %>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<%= form_with(model: user_role) do |form| %>
|
|
2
|
+
<% if user_role.errors.any? %>
|
|
3
|
+
<div style="color: red">
|
|
4
|
+
<h2><%= pluralize(user_role.errors.count, "error") %> prohibited this user_role from being saved:</h2>
|
|
5
|
+
|
|
6
|
+
<ul>
|
|
7
|
+
<% user_role.errors.each do |error| %>
|
|
8
|
+
<li><%= error.full_message %></li>
|
|
9
|
+
<% end %>
|
|
10
|
+
</ul>
|
|
11
|
+
</div>
|
|
12
|
+
<% end %>
|
|
13
|
+
|
|
14
|
+
<div>
|
|
15
|
+
<%= form.submit %>
|
|
16
|
+
</div>
|
|
17
|
+
<% end %>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<p style="color: green"><%= notice %></p>
|
|
2
|
+
|
|
3
|
+
<% content_for :title, "Roles" %>
|
|
4
|
+
|
|
5
|
+
<h1>Roles</h1>
|
|
6
|
+
|
|
7
|
+
<div id="user_roles">
|
|
8
|
+
<% @user_roles.each do |user_role| %>
|
|
9
|
+
<%= render user_role %>
|
|
10
|
+
<p>
|
|
11
|
+
<%= link_to "Show this role", user_role %>
|
|
12
|
+
</p>
|
|
13
|
+
<% end %>
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
<%= link_to "New role", new_user_role_path %>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<p style="color: green"><%= notice %></p>
|
|
2
|
+
|
|
3
|
+
<%= render @user_role %>
|
|
4
|
+
|
|
5
|
+
<div>
|
|
6
|
+
<%= link_to "Edit this role", edit_user_role_path(@user_role) %> |
|
|
7
|
+
<%= link_to "Back to roles", user_roles_path %>
|
|
8
|
+
|
|
9
|
+
<%= button_to "Destroy this role", @user_role, method: :delete %>
|
|
10
|
+
</div>
|
|
@@ -10,11 +10,11 @@
|
|
|
10
10
|
<h5 class="title is-size-5 mb-0">
|
|
11
11
|
<%= @user.full_name %>
|
|
12
12
|
</h5>
|
|
13
|
-
<p><%= @user.title %></p>
|
|
13
|
+
<p class="mb-1"><%= @user.title %></p>
|
|
14
14
|
<div class="level is-mobile">
|
|
15
15
|
<div class="level-left">
|
|
16
16
|
<a class="level-item"
|
|
17
|
-
href="
|
|
17
|
+
href="mailto:<%= @user.email %>">
|
|
18
18
|
<span class="icon is-small mr-2">
|
|
19
19
|
<span class="material-symbols">
|
|
20
20
|
email
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
<%= @user.email %>
|
|
24
24
|
</a>
|
|
25
25
|
<a class="level-item mx-2"
|
|
26
|
-
href="
|
|
26
|
+
href="tel:<%= @user.telephone %>">
|
|
27
27
|
<span class="icon is-small mr-2">
|
|
28
28
|
<span class="material-symbols">
|
|
29
29
|
phone
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
<%
|
|
2
|
+
columns = [{
|
|
3
|
+
label: "ID"
|
|
4
|
+
}, {
|
|
5
|
+
label: "Name"
|
|
6
|
+
}, {
|
|
7
|
+
label: "status"
|
|
8
|
+
}]
|
|
9
|
+
%>
|
|
10
|
+
|
|
11
|
+
<% roles = @user.account.roles.joins("
|
|
12
|
+
LEFT JOIN lesli_shield_user_roles
|
|
13
|
+
ON lesli_shield_user_roles.role_id = lesli_roles.id
|
|
14
|
+
AND lesli_shield_user_roles.user_id = #{@user.id}
|
|
15
|
+
").select(
|
|
16
|
+
"lesli_roles.*",
|
|
17
|
+
"lesli_shield_user_roles.id AS user_role_id"
|
|
18
|
+
)
|
|
19
|
+
%>
|
|
20
|
+
|
|
21
|
+
<%= render(LesliView::Elements::Table.new(:columns => columns)) do |table| %>
|
|
22
|
+
<% roles.each do |role| %>
|
|
23
|
+
<% table.with_row do |row| %>
|
|
24
|
+
<% row.with_cell do %>
|
|
25
|
+
<%= role[:id] %>
|
|
26
|
+
<% end %>
|
|
27
|
+
<% row.with_cell do %>
|
|
28
|
+
<%= role[:name] %>
|
|
29
|
+
<% end %>
|
|
30
|
+
<% row.with_cell do %>
|
|
31
|
+
<%= button_to user_role_path(role),
|
|
32
|
+
class: "mini-toggle #{'active' if role[:user_role_id].present?}",
|
|
33
|
+
method: (role[:user_role_id].present? ? :delete : :patch) do %>
|
|
34
|
+
<span class="mini-toggle-slider"></span>
|
|
35
|
+
<% end %>
|
|
36
|
+
<% end %>
|
|
37
|
+
<% end %>
|
|
38
|
+
<% end %>
|
|
39
|
+
<% end %>
|
|
40
|
+
|
|
41
|
+
<style>
|
|
42
|
+
.mini-toggle {
|
|
43
|
+
position: relative;
|
|
44
|
+
width: 40px;
|
|
45
|
+
height: 20px;
|
|
46
|
+
background: #ccc;
|
|
47
|
+
border-radius: 9999px;
|
|
48
|
+
border: none;
|
|
49
|
+
cursor: pointer;
|
|
50
|
+
padding: 0;
|
|
51
|
+
transition: background 0.25s ease;
|
|
52
|
+
display: inline-block;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.mini-toggle.active {
|
|
56
|
+
background: #22c55e; /* green */
|
|
57
|
+
background: var(--lesli-color-primary)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.mini-toggle-slider {
|
|
61
|
+
position: absolute;
|
|
62
|
+
top: 2px;
|
|
63
|
+
left: 2px;
|
|
64
|
+
width: 16px;
|
|
65
|
+
height: 16px;
|
|
66
|
+
background: white;
|
|
67
|
+
border-radius: 50%;
|
|
68
|
+
transition: transform 0.25s ease;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.mini-toggle.active .mini-toggle-slider {
|
|
72
|
+
transform: translateX(20px);
|
|
73
|
+
}
|
|
74
|
+
</style>
|