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.
Files changed (111) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/stylesheets/lesli_shield/confirmations.css +18732 -0
  3. data/app/assets/stylesheets/lesli_shield/passwords.css +2 -238
  4. data/app/assets/stylesheets/lesli_shield/registrations.css +2 -238
  5. data/app/assets/stylesheets/lesli_shield/sessions.css +2 -238
  6. data/app/controllers/lesli_shield/dashboards_controller.rb +1 -8
  7. data/app/controllers/lesli_shield/invites_controller.rb +80 -0
  8. data/app/controllers/lesli_shield/role/actions_controller.rb +32 -20
  9. data/app/controllers/lesli_shield/roles_controller.rb +16 -8
  10. data/app/controllers/lesli_shield/sessions_controller.rb +5 -8
  11. data/app/controllers/lesli_shield/user/roles_controller.rb +62 -0
  12. data/app/controllers/lesli_shield/users_controller.rb +57 -20
  13. data/app/controllers/users/confirmations_controller.rb +42 -8
  14. data/app/controllers/users/passwords_controller.rb +52 -37
  15. data/app/controllers/users/registrations_controller.rb +2 -8
  16. data/app/controllers/users/sessions_controller.rb +57 -50
  17. data/app/helpers/lesli_shield/invites_helper.rb +4 -0
  18. data/app/helpers/lesli_shield/user/roles_helper.rb +4 -0
  19. data/app/interfaces/lesli_shield/authorization_interface.rb +8 -2
  20. data/app/mailers/lesli_shield/devise_mailer.rb +98 -0
  21. data/app/mailers/lesli_shield/invitation.html.erb +23 -0
  22. data/app/models/concerns/lesli_shield/user_security.rb +222 -0
  23. data/app/models/lesli_shield/account.rb +1 -1
  24. data/app/models/lesli_shield/dashboard.rb +1 -4
  25. data/app/models/lesli_shield/invite.rb +24 -0
  26. data/{lib/vue/confirmations.js → app/models/lesli_shield/role/action.rb} +17 -10
  27. data/{db/migrate/v1/0801003010_create_lesli_shield_dashboards.rb → app/models/lesli_shield/role/privilege.rb} +5 -4
  28. data/app/models/lesli_shield/user/role.rb +8 -0
  29. data/app/models/lesli_shield/user/session.rb +80 -0
  30. data/app/services/lesli_shield/invite_service.rb +43 -0
  31. data/app/services/lesli_shield/role_action_service.rb +118 -0
  32. data/app/services/lesli_shield/role_privilege_service.rb +112 -0
  33. data/app/{operators/lesli_shield/user_registration_operator.rb → services/lesli_shield/user_registration_service.rb} +26 -29
  34. data/app/services/lesli_shield/user_session_service.rb +78 -0
  35. data/app/services/lesli_shield/user_validator_service.rb +221 -0
  36. data/app/views/devise/confirmations/show.html.erb +4 -6
  37. data/app/views/devise/passwords/edit.html.erb +1 -2
  38. data/app/views/devise/passwords/new.html.erb +1 -1
  39. data/app/views/devise/registrations/new.html.erb +5 -4
  40. data/app/views/devise/sessions/new.html.erb +3 -2
  41. data/app/views/devise/shared/_application-devise-simple.erb +59 -0
  42. data/app/views/devise/shared/_application-devise.html.erb +76 -0
  43. data/app/views/lesli_shield/dashboards/_component-calendar.html.erb +1 -0
  44. data/app/views/lesli_shield/dashboards/_component-chart-bar.html.erb +6 -0
  45. data/app/views/lesli_shield/dashboards/_component-chart-line.html.erb +8 -0
  46. data/app/views/lesli_shield/dashboards/_component-count.html.erb +1 -0
  47. data/app/views/lesli_shield/dashboards/_component-date.html.erb +1 -0
  48. data/app/views/lesli_shield/dashboards/_component-weather.html.erb +1 -0
  49. data/app/views/lesli_shield/invites/_form.html.erb +10 -0
  50. data/app/views/lesli_shield/invites/_invite.html.erb +2 -0
  51. data/app/views/lesli_shield/invites/edit.html.erb +12 -0
  52. data/app/views/lesli_shield/invites/index.html.erb +66 -0
  53. data/{db/migrate/v1/0801001710_create_lesli_shield_settings.rb → app/views/lesli_shield/invites/new.html.erb} +9 -10
  54. data/{lib/vue/apps/dashboards/components/engine-version.vue → app/views/lesli_shield/invites/show.html.erb} +26 -43
  55. data/app/views/lesli_shield/partials/_navigation.html.erb +2 -4
  56. data/app/views/lesli_shield/{roles/_form-privileges.html.erb → role/actions/_form.html.erb} +5 -30
  57. data/app/views/lesli_shield/role/actions/index.html.erb +14 -0
  58. data/app/views/lesli_shield/roles/index.html.erb +2 -6
  59. data/app/views/lesli_shield/roles/new.html.erb +0 -11
  60. data/app/views/lesli_shield/roles/show.html.erb +5 -8
  61. data/app/views/lesli_shield/user/roles/_form.html.erb +17 -0
  62. data/app/views/lesli_shield/user/roles/_role.html.erb +2 -0
  63. data/app/views/lesli_shield/user/roles/edit.html.erb +12 -0
  64. data/app/views/lesli_shield/user/roles/index.html.erb +16 -0
  65. data/app/views/lesli_shield/user/roles/new.html.erb +11 -0
  66. data/app/views/lesli_shield/user/roles/show.html.erb +10 -0
  67. data/app/views/lesli_shield/users/{_viewer-activities.html.erb → _activities-viewer.html.erb} +2 -4
  68. data/app/views/lesli_shield/users/_information-card.html.erb +3 -3
  69. data/app/views/lesli_shield/users/_management-privileges.html.erb +74 -0
  70. data/app/views/lesli_shield/users/_management-security.html.erb +5 -0
  71. data/app/views/lesli_shield/users/index.html.erb +3 -7
  72. data/app/views/lesli_shield/users/new.html.erb +5 -11
  73. data/app/views/lesli_shield/users/show.html.erb +7 -5
  74. data/config/initializers/devise.rb +305 -304
  75. data/config/locales/translations.en.yml +4 -1
  76. data/config/locales/translations.es.yml +4 -1
  77. data/config/locales/translations.it.yml +4 -1
  78. data/config/routes.rb +7 -8
  79. data/db/migrate/v1/0801100210_create_lesli_shield_role_actions.rb +48 -0
  80. data/db/migrate/v1/0801100410_create_lesli_shield_role_privileges.rb +45 -0
  81. data/db/migrate/v1/0801110110_create_lesli_shield_user_roles.rb +43 -0
  82. data/db/migrate/v1/0801111210_create_lesli_shield_user_sessions.rb +56 -0
  83. data/db/migrate/v1/0801120110_create_lesli_shield_invites.rb +49 -0
  84. data/lib/lesli_shield/router.rb +21 -0
  85. data/lib/lesli_shield/version.rb +2 -2
  86. data/lib/lesli_shield.rb +1 -1
  87. data/lib/scss/confirmations.scss +24 -24
  88. data/lib/tasks/lesli_shield_tasks.rake +1 -1
  89. data/readme.md +59 -20
  90. metadata +57 -33
  91. data/app/controllers/lesli_shield/dashboard/components_controller.rb +0 -60
  92. data/app/models/lesli_shield/dashboard/component.rb +0 -18
  93. data/app/views/lesli_shield/dashboards/edit.html.erb +0 -1
  94. data/app/views/lesli_shield/dashboards/index.html.erb +0 -9
  95. data/app/views/lesli_shield/dashboards/new.html.erb +0 -1
  96. data/app/views/lesli_shield/dashboards/show.html.erb +0 -1
  97. data/app/views/lesli_shield/roles/_session.html.erb +0 -2
  98. data/app/views/lesli_shield/roles/edit.html.erb +0 -12
  99. data/app/views/lesli_shield/roles/update.turbo_stream.erb +0 -3
  100. data/app/views/lesli_shield/users/update.turbo_stream.erb +0 -3
  101. data/lib/lesli_shield/routing.rb +0 -23
  102. data/lib/vue/application.js +0 -83
  103. data/lib/vue/apps/sessions/index.vue +0 -50
  104. data/lib/vue/passwords.js +0 -137
  105. data/lib/vue/registrations.js +0 -144
  106. data/lib/vue/sessions.js +0 -148
  107. data/lib/vue/stores/sessions.js +0 -43
  108. data/lib/vue/stores/translations.json +0 -162
  109. /data/app/views/lesli_shield/roles/{_form-information.html.erb → _form.html.erb} +0 -0
  110. /data/db/migrate/v1/{0801120310_create_lesli_shield_user_shortcuts.rb → 0801111010_create_lesli_shield_user_shortcuts.rb} +0 -0
  111. /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,6 @@
1
+
2
+ <%= render(LesliView::Widgets::Chart.new("Priorities", {
3
+ "High": 10,
4
+ "Low": 16,
5
+ "Medium": 4
6
+ }, type: :bar))%>
@@ -0,0 +1,8 @@
1
+
2
+ <%= render(LesliView::Widgets::Chart.new("Requests", {
3
+ "1": 13,
4
+ "2": 17,
5
+ "3": 10,
6
+ "4": 5,
7
+ "5": 15,
8
+ }, type: :line))%>
@@ -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,2 @@
1
+ <div id="<%= dom_id invite %>">
2
+ </div>
@@ -0,0 +1,12 @@
1
+ <% content_for :title, "Editing invite" %>
2
+
3
+ <h1>Editing invite</h1>
4
+
5
+ <%= render "form", invite: @invite %>
6
+
7
+ <br>
8
+
9
+ <div>
10
+ <%= link_to "Show this invite", @invite %> |
11
+ <%= link_to "Back to invites", invites_path %>
12
+ </div>
@@ -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
- =begin
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 Platform.
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
- =end
32
-
33
- class CreateLesliShieldSettings < ActiveRecord::Migration[6.0]
34
- def change
35
- create_table_lesli_shared_settings_10(:lesli_shield)
36
- end
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
- <script setup>
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
- import { onMounted, inject, ref } from "vue"
36
-
37
-
38
- // ·
39
- const url = inject("url")
40
- const http = inject("http")
41
-
42
-
43
- // ·
44
- const lesliVersion = ref({
45
- name: "",
46
- code: "",
47
- path: "",
48
- version: "",
49
- build: ""
50
- })
51
-
52
-
53
- // ·
54
- onMounted(() => {
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.settings_path, "Settings", "ri-settings-3-line") %>
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
- <%= render LesliView::Elements::Table.new(:columns => columns) do |table| %>
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
- method: (action[:active] == 1 ? :delete : :patch),
69
- class: "mini-toggle #{action[:active] == 1 ? 'active' : ''}",
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
- <script>
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)) do %>
33
- Add new
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,11 +0,0 @@
1
- <% content_for :title, "New session" %>
2
-
3
- <h1>New session</h1>
4
-
5
- <%= render "form", session: @session %>
6
-
7
- <br>
8
-
9
- <div>
10
- <%= link_to "Back to sessions", sessions_path %>
11
- </div>
@@ -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 LesliView::Components::Tabs.new() do |tabs| %>
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,2 @@
1
+ <div id="<%= dom_id role %>">
2
+ </div>
@@ -0,0 +1,12 @@
1
+ <% content_for :title, "Editing role" %>
2
+
3
+ <h1>Editing role</h1>
4
+
5
+ <%= render "form", user_role: @user_role %>
6
+
7
+ <br>
8
+
9
+ <div>
10
+ <%= link_to "Show this role", @user_role %> |
11
+ <%= link_to "Back to roles", user_roles_path %>
12
+ </div>
@@ -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,11 @@
1
+ <% content_for :title, "New role" %>
2
+
3
+ <h1>New role</h1>
4
+
5
+ <%= render "form", user_role: @user_role %>
6
+
7
+ <br>
8
+
9
+ <div>
10
+ <%= link_to "Back to roles", user_roles_path %>
11
+ </div>
@@ -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>
@@ -1,5 +1,3 @@
1
-
2
-
3
-
4
- <%#= dd @activities %>
1
+ <div class="box">
5
2
  <%= render(LesliView::Components::Timeline.new(:activities => @activities)) %>
3
+ </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="'mailto:'+storeUser.user.email">
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="'tel:'+storeUser.user.telephone">
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>
@@ -0,0 +1,5 @@
1
+ <div class="box">
2
+ <%= render(LesliView::Elements::Button.new('Revoke access')) %>
3
+ <%= render(LesliView::Elements::Button.new('Set password as expired')) %>
4
+ <%= render(LesliView::Elements::Button.new('Force password update')) %>
5
+ </div>