lesli_admin 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +7 -0
  2. data/Rakefile +5 -0
  3. data/app/assets/config/lesli_admin_manifest.js +38 -0
  4. data/app/assets/javascripts/lesli_admin/application.js +3713 -0
  5. data/app/assets/stylesheets/lesli_admin/application.css +15 -0
  6. data/app/controllers/lesli_admin/accounts_controller.rb +125 -0
  7. data/app/controllers/lesli_admin/application_controller.rb +4 -0
  8. data/app/controllers/lesli_admin/dashboards_controller.rb +60 -0
  9. data/app/controllers/lesli_admin/users_controller.rb +244 -0
  10. data/app/helpers/lesli_admin/application_helper.rb +4 -0
  11. data/app/helpers/lesli_admin/dashboards_helper.rb +4 -0
  12. data/app/jobs/lesli_admin/application_job.rb +4 -0
  13. data/app/mailers/lesli_admin/application_mailer.rb +6 -0
  14. data/app/models/lesli_admin/account.rb +66 -0
  15. data/app/models/lesli_admin/application_record.rb +5 -0
  16. data/app/models/lesli_admin/dashboard.rb +4 -0
  17. data/app/models/lesli_admin/user.rb +4 -0
  18. data/app/services/lesli_admin/user_service.rb +300 -0
  19. data/app/views/layouts/lesli_admin/application.html.erb +15 -0
  20. data/app/views/lesli_admin/accounts/_account.html.erb +2 -0
  21. data/app/views/lesli_admin/accounts/_form.html.erb +17 -0
  22. data/app/views/lesli_admin/accounts/edit.html.erb +10 -0
  23. data/app/views/lesli_admin/accounts/index.html.erb +34 -0
  24. data/app/views/lesli_admin/accounts/new.html.erb +9 -0
  25. data/app/views/lesli_admin/accounts/show.html.erb +34 -0
  26. data/app/views/lesli_admin/dashboards/_dashboard.html.erb +2 -0
  27. data/app/views/lesli_admin/dashboards/_form.html.erb +17 -0
  28. data/app/views/lesli_admin/dashboards/edit.html.erb +10 -0
  29. data/app/views/lesli_admin/dashboards/index.html.erb +14 -0
  30. data/app/views/lesli_admin/dashboards/new.html.erb +9 -0
  31. data/app/views/lesli_admin/dashboards/show.html.erb +1 -0
  32. data/app/views/lesli_admin/partials/_engine-navigation.html.erb +52 -0
  33. data/app/views/lesli_admin/users/edit.html.erb +10 -0
  34. data/app/views/lesli_admin/users/index.html.erb +34 -0
  35. data/app/views/lesli_admin/users/new.html.erb +34 -0
  36. data/app/views/lesli_admin/users/show.html.erb +10 -0
  37. data/config/routes.rb +13 -0
  38. data/lib/lesli_admin/engine.rb +18 -0
  39. data/lib/lesli_admin/version.rb +3 -0
  40. data/lib/lesli_admin.rb +6 -0
  41. data/lib/tasks/lesli_admin_tasks.rake +4 -0
  42. data/lib/vue/application.js +153 -0
  43. data/lib/vue/apps/account/components/address-form.vue +134 -0
  44. data/lib/vue/apps/account/components/contact-form.vue +162 -0
  45. data/lib/vue/apps/account/components/form-information.vue +107 -0
  46. data/lib/vue/apps/account/show.vue +89 -0
  47. data/lib/vue/apps/dashboard/show.vue +33 -0
  48. data/lib/vue/apps/profile/components/change-email.vue +38 -0
  49. data/lib/vue/apps/profile/components/subscriptions.vue +94 -0
  50. data/lib/vue/apps/profile/show.vue +141 -0
  51. data/lib/vue/apps/users/components/information-card.vue +119 -0
  52. data/lib/vue/apps/users/components/information-form.vue +180 -0
  53. data/lib/vue/apps/users/components/integrations-information.vue +61 -0
  54. data/lib/vue/apps/users/components/management-roles.vue +109 -0
  55. data/lib/vue/apps/users/components/management-security.vue +113 -0
  56. data/lib/vue/apps/users/components/management-sessions.vue +106 -0
  57. data/lib/vue/apps/users/components/management-settings.vue +94 -0
  58. data/lib/vue/apps/users/index.vue +201 -0
  59. data/lib/vue/apps/users/new.vue +181 -0
  60. data/lib/vue/apps/users/show.vue +101 -0
  61. data/lib/vue/stores/account.js +113 -0
  62. data/lib/vue/stores/accountSettings.js +342 -0
  63. data/lib/vue/stores/descriptor.js +116 -0
  64. data/lib/vue/stores/descriptors.js +167 -0
  65. data/lib/vue/stores/integration.js +103 -0
  66. data/lib/vue/stores/role.js +243 -0
  67. data/lib/vue/stores/roles.js +89 -0
  68. data/lib/vue/stores/systemController.js +67 -0
  69. data/lib/vue/stores/user.js +319 -0
  70. data/lib/vue/stores/users.js +150 -0
  71. data/readme.md +28 -0
  72. metadata +130 -0
@@ -0,0 +1,109 @@
1
+ <script setup>
2
+ /*
3
+
4
+ Lesli
5
+
6
+ Copyright (c) 2023, Lesli Technologies, S. A.
7
+
8
+ This program is free software: you can redistribute it and/or modify
9
+ it under the terms of the GNU General Public License as published by
10
+ the Free Software Foundation, either version 3 of the License, or
11
+ (at your option) any later version.
12
+
13
+ This program is distributed in the hope that it will be useful,
14
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ GNU General Public License for more details.
17
+
18
+ You should have received a copy of the GNU General Public License
19
+ along with this program. If not, see http://www.gnu.org/licenses/.
20
+
21
+ Lesli · Your Smart Business Assistant.
22
+
23
+ Made with ♥ by https://www.lesli.tech
24
+ Building a better future, one line of code at a time.
25
+
26
+ @contact hello@lesli.tech
27
+ @website https://lesli.tech
28
+ @license GPLv3 http://www.gnu.org/licenses/gpl-3.0.en.html
29
+
30
+ // · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
31
+ // ·
32
+
33
+ */
34
+
35
+
36
+
37
+ // · import vue tools
38
+ import { ref, reactive, onMounted, watch, computed } from "vue"
39
+
40
+
41
+ // · import lesli stores
42
+ import { useUser } from "LesliApp/administration/stores/user"
43
+ import { useRoles } from "LesliApp/administration/stores/roles"
44
+
45
+
46
+ // · implement stores
47
+ const storeUser = useUser()
48
+ const storeRoles = useRoles()
49
+
50
+
51
+ // ·
52
+ const translations = {
53
+ shared: I18n.t("core.shared"),
54
+ passwords: I18n.t("core.users/passwords"),
55
+ users: I18n.t("core.users")
56
+ }
57
+
58
+
59
+ // ·
60
+ function updateRole(role){
61
+ if (role.active) {
62
+ storeUser.postRole(role)
63
+ } else {
64
+ storeUser.deleteRole(role)
65
+ }
66
+ }
67
+
68
+
69
+ // ·
70
+ onMounted(() => {
71
+ storeUser.getRoles()
72
+ })
73
+ </script>
74
+ <template>
75
+ <div class="media px-6" v-for="role in storeUser.roles">
76
+ <div class="media-content pt-4">
77
+ <h4>{{ role.name }}</h4>
78
+ <p style="color:#aaa;">
79
+ {{ role.description }}
80
+ Profile view, Role view, Role create, Role update
81
+ </p>
82
+ </div>
83
+ <div class="media-right pt-4">
84
+ <lesli-toggle v-model="role.active" @change="updateRole(role)">
85
+ </lesli-toggle>
86
+ </div>
87
+ </div>
88
+ <lesli-empty v-if="storeUser.roles.length == 0"></lesli-empty>
89
+ <!--
90
+ <div class="roles-types">
91
+ <div
92
+ class="card roles-types-item p-4 is-flex is-flex-direction-column is-justify-content-space-between is-clickable"
93
+ v-for="role in storeUser.options.roles"
94
+ :key="role">
95
+ <div class="role-type-title">
96
+ <span class="has-text-weight-semibold is-size-5 ">
97
+ {{ role.name }}
98
+ </span>
99
+ </div>
100
+ <div>
101
+ <span>Permission level: {{ role.object_level_permission }} </span>
102
+ </div>
103
+ <div class="is-flex is-justify-content-space-between is-align-items-center">
104
+ <lesli-toggle v-model="storeUser.rolesToggle[role.id]" v-on:update:modelValue="updateRole(role,storeUser.rolesToggle[role.id])" ></lesli-toggle>
105
+ </div>
106
+ </div>
107
+ </div>
108
+ -->
109
+ </template>
@@ -0,0 +1,113 @@
1
+ <script setup>
2
+ /*
3
+
4
+ Lesli
5
+
6
+ Copyright (c) 2023, Lesli Technologies, S. A.
7
+
8
+ This program is free software: you can redistribute it and/or modify
9
+ it under the terms of the GNU General Public License as published by
10
+ the Free Software Foundation, either version 3 of the License, or
11
+ (at your option) any later version.
12
+
13
+ This program is distributed in the hope that it will be useful,
14
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ GNU General Public License for more details.
17
+
18
+ You should have received a copy of the GNU General Public License
19
+ along with this program. If not, see http://www.gnu.org/licenses/.
20
+
21
+ Lesli · Your Smart Business Assistant.
22
+
23
+ Made with ♥ by https://www.lesli.tech
24
+ Building a better future, one line of code at a time.
25
+
26
+ @contact hello@lesli.tech
27
+ @website https://lesli.tech
28
+ @license GPLv3 http://www.gnu.org/licenses/gpl-3.0.en.html
29
+
30
+ // · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
31
+ // ·
32
+
33
+ */
34
+
35
+
36
+
37
+ // · import lesli stores
38
+ import { useUser } from "LesliApp/administration/stores/user"
39
+
40
+
41
+ // · implement stores
42
+ const storeUser = useUser()
43
+
44
+
45
+ // · translations
46
+ const translations = {
47
+ users: I18n.t("core.users"),
48
+ shared: I18n.t("core.shared")
49
+ }
50
+
51
+
52
+ </script>
53
+ <template>
54
+ <div>
55
+ <fieldset class="mb-4">
56
+ <legend>Force the user to change the password</legend>
57
+ <lesli-button
58
+ icon="lock_reset"
59
+ @click="storeUser.doRequestPassword">
60
+ {{ translations.users.view_btn_request_password || "Request password" }}
61
+ </lesli-button>
62
+ </fieldset>
63
+
64
+ <fieldset class="mb-4">
65
+ <legend>Generate a new password for the user</legend>
66
+ <lesli-button
67
+ icon="key"
68
+ @click="storeUser.doPasswordReset">
69
+ {{ translations.users.view_btn_password_reset || "Password reset" }}
70
+ </lesli-button>
71
+ </fieldset>
72
+
73
+ <fieldset class="mb-4">
74
+ <legend>Close all the active sessions of the user</legend>
75
+ <lesli-button
76
+ icon="logout"
77
+ @click="storeUser.doLogout">
78
+ {{ translations.users.view_btn_logout }}
79
+ </lesli-button>
80
+ </fieldset>
81
+
82
+ <fieldset class="mb-4">
83
+ <legend>Remove all user access</legend>
84
+ <lesli-button
85
+ danger
86
+ icon="lock_outline"
87
+ @click="storeUser.doRevokeAccess">
88
+ {{ translations.users.view_btn_revoke_access }}
89
+ </lesli-button>
90
+ </fieldset>
91
+
92
+ <br><br>
93
+
94
+ <fieldset class="mb-4">
95
+ <lesli-button
96
+ danger
97
+ icon="delete_forever"
98
+ @click="storeUser.deleteUser">
99
+ {{ translations.users.view_btn_delete_user }}
100
+ </lesli-button>
101
+ </fieldset>
102
+ </div>
103
+ </template>
104
+ <style scoped>
105
+ fieldset {
106
+ padding: 1.6rem;
107
+ border: 1px solid #ccc;
108
+ border-radius: 4px;
109
+ }
110
+ legend {
111
+ color: #555;
112
+ }
113
+ </style>
@@ -0,0 +1,106 @@
1
+ <script setup>
2
+ /*
3
+
4
+ Lesli
5
+
6
+ Copyright (c) 2023, Lesli Technologies, S. A.
7
+
8
+ This program is free software: you can redistribute it and/or modify
9
+ it under the terms of the GNU General Public License as published by
10
+ the Free Software Foundation, either version 3 of the License, or
11
+ (at your option) any later version.
12
+
13
+ This program is distributed in the hope that it will be useful,
14
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ GNU General Public License for more details.
17
+
18
+ You should have received a copy of the GNU General Public License
19
+ along with this program. If not, see http://www.gnu.org/licenses/.
20
+
21
+ Lesli · Your Smart Business Assistant.
22
+
23
+ Made with ♥ by https://www.lesli.tech
24
+ Building a better future, one line of code at a time.
25
+
26
+ @contact hello@lesli.tech
27
+ @website https://lesli.tech
28
+ @license GPLv3 http://www.gnu.org/licenses/gpl-3.0.en.html
29
+
30
+ // · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
31
+ // ·
32
+
33
+ */
34
+
35
+
36
+
37
+ // · import vue tools
38
+ import { ref, reactive, onMounted, watch, computed } from "vue"
39
+
40
+
41
+ // · import vue router composable
42
+ import { useRoute } from "vue-router"
43
+
44
+
45
+ // · import lesli stores
46
+ import { useUser } from "LesliApp/administration/stores/user"
47
+
48
+
49
+ // · implement stores
50
+ const storeUser = useUser()
51
+
52
+
53
+ // · initialize/inject plugins
54
+ const route = useRoute()
55
+
56
+
57
+ // ·
58
+ const translations = {
59
+ users: I18n.t("core.users"),
60
+ shared: I18n.t("core.shared")
61
+ }
62
+
63
+
64
+ // ·
65
+ const columns = [{
66
+ field: 'id',
67
+ label: 'ID'
68
+ }, {
69
+ field: 'user_agent',
70
+ label: 'Device'
71
+ }, {
72
+ field: 'session_source',
73
+ label: 'Source'
74
+ }, {
75
+ field: 'created_at_date',
76
+ label: 'Created at'
77
+ }, {
78
+ field: 'last_used_at_string',
79
+ label: 'Last used at'
80
+ }]
81
+
82
+
83
+ // ·
84
+ onMounted(() => {
85
+ storeUser.fetchSessions()
86
+ })
87
+
88
+ </script>
89
+ <template>
90
+ <lesli-card>
91
+ <lesli-toolbar>
92
+ <lesli-button icon="refresh">
93
+ Reload
94
+ </lesli-button>
95
+ </lesli-toolbar>
96
+ <lesli-table
97
+ :columns="columns"
98
+ :records="storeUser.sessions.records">
99
+ <template #buttons="{ record, value }">
100
+ <lesli-button danger icon="delete" @click="storeUser.deleteSession(record.id)">
101
+ {{ translations.users.view_btn_logout }}
102
+ </lesli-button>
103
+ </template>
104
+ </lesli-table>
105
+ </lesli-card>
106
+ </template>
@@ -0,0 +1,94 @@
1
+ <script setup>
2
+ /*
3
+
4
+ Lesli
5
+
6
+ Copyright (c) 2023, Lesli Technologies, S. A.
7
+
8
+ This program is free software: you can redistribute it and/or modify
9
+ it under the terms of the GNU General Public License as published by
10
+ the Free Software Foundation, either version 3 of the License, or
11
+ (at your option) any later version.
12
+
13
+ This program is distributed in the hope that it will be useful,
14
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ GNU General Public License for more details.
17
+
18
+ You should have received a copy of the GNU General Public License
19
+ along with this program. If not, see http://www.gnu.org/licenses/.
20
+
21
+ Lesli · Your Smart Business Assistant.
22
+
23
+ Made with ♥ by https://www.lesli.tech
24
+ Building a better future, one line of code at a time.
25
+
26
+ @contact hello@lesli.tech
27
+ @website https://lesli.tech
28
+ @license GPLv3 http://www.gnu.org/licenses/gpl-3.0.en.html
29
+
30
+ // · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
31
+ // ·
32
+
33
+ */
34
+
35
+
36
+ // · import vue tools
37
+ import { ref, reactive, onMounted, watch, computed } from "vue"
38
+
39
+
40
+ // · import lesli stores
41
+ import { useUser } from "LesliApp/administration/stores/user"
42
+
43
+
44
+ // · implement stores
45
+ const storeUser = useUser()
46
+
47
+
48
+ // · translations
49
+ const translations = {
50
+ users: I18n.t("core.users"),
51
+ shared: I18n.t("core.shared")
52
+ }
53
+
54
+
55
+ // · initializing
56
+ onMounted(() => {
57
+ storeUser.getOptions()
58
+ })
59
+ </script>
60
+ <template>
61
+ <lesli-form @submit="storeUser.postLanguage">
62
+ <div class="field is-horizontal">
63
+ <div class="field-label">
64
+ <label class="label">Select preferred language </label>
65
+ </div>
66
+ <div class="field-body">
67
+ <div class="field is-narrow">
68
+ <div class="control">
69
+ <div class="select">
70
+ <lesli-select
71
+ icon="language"
72
+ v-model="storeUser.user.locale.value"
73
+ :options="storeUser.options.locales">
74
+ </lesli-select>
75
+ </div>
76
+ </div>
77
+ </div>
78
+ </div>
79
+ </div>
80
+ <div class="field is-horizontal">
81
+ <div class="field-label is-normal">
82
+ </div>
83
+ <div class="field-body">
84
+ <div class="field">
85
+ <div class="control">
86
+ <lesli-button icon="save">
87
+ {{ translations.shared.view_btn_save }}
88
+ </lesli-button>
89
+ </div>
90
+ </div>
91
+ </div>
92
+ </div>
93
+ </lesli-form>
94
+ </template>
@@ -0,0 +1,201 @@
1
+ <script setup>
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
+
34
+ // · import vue tools
35
+ import { ref, reactive, onMounted, watch, computed, inject } from "vue"
36
+ import { useRouter, useRoute } from "vue-router"
37
+
38
+
39
+ // · import lesli stores
40
+ import { useUsers } from "LesliAdmin/stores/users"
41
+
42
+
43
+ // · initialize/inject plugins
44
+ const router = useRouter()
45
+ const msg = inject("msg")
46
+ const url = inject("url")
47
+
48
+
49
+ // · implement stores
50
+ const storeUsers = useUsers()
51
+
52
+
53
+ // · translations
54
+ const translations = {
55
+ core: {
56
+ roles: I18n.t("core.roles"),
57
+ users: I18n.t("core.users"),
58
+ shared: I18n.t("core.shared")
59
+ }
60
+ }
61
+
62
+
63
+ // ·
64
+ const columns = [{
65
+ field: "id",
66
+ label: "ID",
67
+ sort: true
68
+ }, {
69
+ field: "name",
70
+ label: translations.core.users.view_table_header_name,
71
+ sort: true
72
+ }, {
73
+ field: "email",
74
+ label: translations.core.users.view_table_header_email,
75
+ sort: true
76
+ }, {
77
+ field: "rolenames",
78
+ label: translations.core.users.view_table_header_role,
79
+ sort: true
80
+ }, {
81
+ field: "active",
82
+ label: translations.core.users.view_table_header_status,
83
+ sort: true,
84
+ custom: true
85
+ }, {
86
+ field: "current_sign_in_at_string",
87
+ label: translations.core.users.view_table_header_last_sign_in,
88
+ sort: true
89
+ }, {
90
+ field: "last_action_performed_at_string",
91
+ label: translations.core.users.view_text_last_activity_at,
92
+ sort: true
93
+ }]
94
+
95
+
96
+ // ·
97
+ const selection = ref()
98
+
99
+ // · defining props
100
+ const props = defineProps({
101
+ appMountPath: {
102
+ type: String,
103
+ required: false,
104
+ default: "lesli/users",
105
+ },
106
+ defaultRole: {
107
+ type: String,
108
+ required: false,
109
+ default: "",
110
+ }
111
+ })
112
+
113
+
114
+ // · initializing
115
+ onMounted(() => {
116
+ storeUsers.fetchUsers()
117
+ })
118
+
119
+
120
+ //
121
+ function showUser(user) {
122
+ router.push(url.root(props.appMountPath+`/${user.id}`).s)
123
+ }
124
+ </script>
125
+ <template>
126
+ <lesli-application>
127
+ <lesli-header :title="translations.core.users.view_text_title_users + ' (' +storeUsers.index.pagination.total+ ')' ">
128
+ <lesli-button icon="add" :to="url.root(props.appMountPath+`/new`)">
129
+ {{ translations.core.users.view_text_add_user }}
130
+ </lesli-button>
131
+ <lesli-button
132
+ icon="refresh"
133
+ :loading="storeUsers.loading"
134
+ @click="storeUsers.getUsers()">
135
+ {{ translations.core.shared.view_text_btn_reload }}
136
+ </lesli-button>
137
+ </lesli-header>
138
+
139
+ <!--
140
+ <lesli-toolbar
141
+ @search="storeUsers.search"
142
+ :search-placeholder="translations.core.users.view_toolbar_filter_placeholder_search">
143
+ <lesli-select :options="[{
144
+ label: translations.core.users.view_toolbar_filter_placeholder_all_users,
145
+ value: null
146
+ }, {
147
+ label: translations.core.users.view_toolbar_filter_placeholder_active_users,
148
+ value: 'active'
149
+ }, {
150
+ label: translations.core.users.view_toolbar_filter_placeholder_inactive_users,
151
+ value: 'inactive'
152
+ }]"
153
+ v-model="storeUsers.filters.status"
154
+ @change="storeUsers.fetchIndex()">
155
+ </lesli-select>
156
+ <lesli-select :options="storeUsers.roles_options"
157
+ v-model="storeUsers.filters.role"
158
+ @change="storeUsers.fetchIndex()">
159
+ </lesli-select>
160
+ </lesli-toolbar>
161
+ -->
162
+
163
+ <lesli-table
164
+ :loading="storeUsers.loading"
165
+ :columns="columns"
166
+ :records="storeUsers.index.records"
167
+ :pagination="storeUsers.index.pagination"
168
+ :link="(user) => url.root(props.appMountPath+`/${user.id}`).s"
169
+ @paginate="storeUsers.paginateIndex"
170
+ @sort="storeUsers.sortIndex">
171
+
172
+ <template #active="{ value }">
173
+ <span class="tag is-success" v-if="value">
174
+ {{ translations.core.shared.view_text_active }}
175
+ </span>
176
+ <span class="tag is-warning" v-if="!value">
177
+ {{ translations.core.shared.view_text_inactive }}
178
+ </span>
179
+ </template>
180
+
181
+ <template #options="{ record, value }">
182
+ <a class="dropdown-item" @click="storeUsers.doLogout(record.id)">
183
+ <span class="material-icons">
184
+ logout
185
+ </span>
186
+ <span>
187
+ {{ translations.core.users.view_btn_logout }}
188
+ </span>
189
+ </a>
190
+ <a class="dropdown-item" @click="storeUsers.doLock(record.id)">
191
+ <span class="material-icons">
192
+ lock
193
+ </span>
194
+ <span>
195
+ {{ translations.core.users.view_btn_revoke_access }}
196
+ </span>
197
+ </a>
198
+ </template>
199
+ </lesli-table>
200
+ </lesli-application>
201
+ </template>