lesli_admin 0.2.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.
@@ -18,18 +18,17 @@ GNU General Public License for more details.
18
18
  You should have received a copy of the GNU General Public License
19
19
  along with this program. If not, see http://www.gnu.org/licenses/.
20
20
 
21
- Lesli · Your Smart Business Assistant.
21
+ Lesli · Ruby on Rails SaaS Development Framework.
22
22
 
23
23
  Made with ♥ by https://www.lesli.tech
24
24
  Building a better future, one line of code at a time.
25
25
 
26
26
  @contact hello@lesli.tech
27
- @website https://lesli.tech
27
+ @website https://www.lesli.tech
28
28
  @license GPLv3 http://www.gnu.org/licenses/gpl-3.0.en.html
29
29
 
30
- // · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
30
+ // · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
31
31
  // ·
32
-
33
32
  */
34
33
 
35
34
 
@@ -40,7 +39,7 @@ import { useRouter, useRoute } from 'vue-router'
40
39
 
41
40
 
42
41
  // · import lesli stores
43
- import { useUser } from "Lesli/stores/user"
42
+ import { useUser } from "LesliAdmin/stores/user"
44
43
 
45
44
 
46
45
  // · implement stores
@@ -48,9 +47,10 @@ const storeUser = useUser()
48
47
  const router = useRouter()
49
48
  const route = useRoute()
50
49
 
51
- // · import profile components
52
50
 
51
+ // · import profile components
53
52
  import informationCard from "LesliAdmin/apps/users/components/information-card.vue"
53
+ import informationForm from "LesliAdmin/apps/users/components/information-form.vue"
54
54
  /*
55
55
  import informationForm from "CloudAdmin/apps/users/components/information-form.vue"
56
56
 
@@ -88,15 +88,19 @@ const tab = ref(0)
88
88
 
89
89
  // ·
90
90
  onMounted(() => {
91
- //storeUser.getUser()
91
+ storeUser.getUser()
92
92
  //storeUser.getOptions()
93
93
  })
94
94
 
95
95
  </script>
96
96
  <template>
97
97
  <lesli-application-container>
98
- {{ storeProfile.profile }}
99
98
  <information-card></information-card>
99
+ <lesli-tabs v-model="tab">
100
+ <lesli-tab-item icon="info_outline" title="Information">
101
+ <information-form></information-form>
102
+ </lesli-tab-item>
103
+ </lesli-tabs>
100
104
  </lesli-application-container>
101
105
  <!--
102
106
  <application-component>
@@ -117,7 +117,6 @@ const props = defineProps({
117
117
  // · initializing
118
118
  onMounted(() => {
119
119
  storeUsers.fetchUsers()
120
- i18n.t("lesli_admin.users.title_users")
121
120
  })
122
121
 
123
122
 
@@ -37,7 +37,7 @@ import { useRouter, useRoute } from 'vue-router'
37
37
 
38
38
 
39
39
  // · import lesli stores
40
- import { useUser } from "Lesli/stores/user"
40
+ import { useUser } from "LesliAdmin/stores/user"
41
41
 
42
42
 
43
43
  // · implement stores
@@ -1,20 +1,38 @@
1
1
  {
2
2
  "en": {
3
- "dashboards": {
4
- "button_my": "My button in my dashboard",
5
- "column_prueba_de_calendario": "my calendar"
3
+ "lesli": {
4
+ "shared": {
5
+ "title_lesli": ":lesli.shared.title_lesli:"
6
+ },
7
+ "users": {
8
+ "title_users": "Users"
9
+ }
6
10
  },
7
- "users": {
8
- "title_users": "Users"
11
+ "lesli_admin": {
12
+ "shared": {
13
+ "title_lesli": ":lesli.shared.title_lesli:"
14
+ },
15
+ "users": {
16
+ "title_users": "Users"
17
+ }
9
18
  }
10
19
  },
11
20
  "es": {
12
- "dashboards": {
13
- "button_my": "Mi boton en mi dashboard",
14
- "column_prueba_de_calendario": ":lesli_driver.dashboards.column_prueba_de_calendario:"
21
+ "lesli": {
22
+ "shared": {
23
+ "title_lesli": "Lesli en español "
24
+ },
25
+ "users": {
26
+ "title_users": "Usuarios"
27
+ }
15
28
  },
16
- "users": {
17
- "title_users": "Usuarios"
29
+ "lesli_admin": {
30
+ "shared": {
31
+ "title_lesli": "Lesli en español "
32
+ },
33
+ "users": {
34
+ "title_users": "Usuarios"
35
+ }
18
36
  }
19
37
  }
20
38
  }
@@ -0,0 +1,331 @@
1
+ /*
2
+ Lesli
3
+
4
+ Copyright (c) 2023, Lesli Technologies, S. A.
5
+
6
+ This program is free software: you can redistribute it and/or modify
7
+ it under the terms of the GNU General Public License as published by
8
+ the Free Software Foundation, either version 3 of the License, or
9
+ (at your option) any later version.
10
+
11
+ This program is distributed in the hope that it will be useful,
12
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ GNU General Public License for more details.
15
+
16
+ You should have received a copy of the GNU General Public License
17
+ along with this program. If not, see http://www.gnu.org/licenses/.
18
+
19
+ Lesli · Ruby on Rails Development Platform.
20
+
21
+ Made with ♥ by https://www.lesli.tech
22
+ Building a better future, one line of code at a time.
23
+
24
+ @contact hello@lesli.tech
25
+ @website https://www.lesli.tech
26
+ @license GPLv3 http://www.gnu.org/licenses/gpl-3.0.en.html
27
+
28
+ // · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
29
+ // ·
30
+ */
31
+
32
+
33
+ // ·
34
+ import { defineStore } from "pinia"
35
+
36
+
37
+ // ·
38
+ export const useUser = defineStore("lesli.user", {
39
+ state: () => {
40
+ return {
41
+ options: {
42
+ regions: [],
43
+ locales: [],
44
+ salutations: [],
45
+ mfa_methods: []
46
+ },
47
+ user: {
48
+ roles_id: null,
49
+ email: null,
50
+ alias: null,
51
+ first_name: null,
52
+ last_name: null,
53
+ telephone: null,
54
+ detail_attributes: {
55
+ salutation: null,
56
+ title: null,
57
+ }
58
+ },
59
+ roles: [],
60
+ sessions: {
61
+ pagination: {},
62
+ records: []
63
+ },
64
+ options: {
65
+ salutations: [],
66
+ locales: []
67
+ }
68
+ }
69
+ },
70
+ getters: {
71
+ initials() {
72
+ let initials = ""
73
+ if (this.user?.first_name) initials += this.user?.first_name[0];
74
+ if (this.user?.last_name) initials += this.user?.last_name[0];
75
+ return initials.toUpperCase()
76
+ }
77
+ },
78
+ actions: {
79
+
80
+ getOptions() {
81
+ this.http.get(this.url.lesli("users/options")).then(result => {
82
+ this.options = result
83
+ })
84
+ },
85
+
86
+ getUser(id=null) {
87
+
88
+ let url = this.url.admin("profile")
89
+
90
+ if (id !== null) {
91
+ console.log("aqui")
92
+ url = this.url.admin("users/:id", id)
93
+ }
94
+
95
+ // get an specifick user if id is provided
96
+ this.http.get(url).then(result => {
97
+ this.user = result
98
+ this.user.password = ""
99
+ this.user.password_confirmation = ""
100
+
101
+ this.language = result.locale ? result.locale.value : this.language
102
+
103
+ // Backend should return the list of roles ordered by object level permission
104
+ this.role_names = result.roles[0].name
105
+
106
+ }).catch(error => {
107
+ this.msg.danger(I18n.t("core.shared.messages_danger_internal_error"))
108
+ }).finally(() => {
109
+ this.loading = false
110
+ })
111
+ },
112
+
113
+ putUser() {
114
+ this.http.put(this.url.lesli("users/:id", this.user.id), {
115
+ user: {
116
+ active: this.user.active,
117
+ alias: this.user.alias,
118
+ first_name: this.user.first_name,
119
+ last_name: this.user.last_name,
120
+ telephone: this.user.telephone,
121
+ detail_attributes: {
122
+ title: this.user.detail_attributes.title,
123
+ salutation: this.user.detail_attributes.salutation
124
+ }
125
+ }
126
+ }).then(result => {
127
+ this.msg.success(I18n.t("core.users.messages_success_operation"))
128
+ }).catch(error => {
129
+ this.msg.danger(I18n.t("core.shared.messages_danger_internal_error"))
130
+ })
131
+ },
132
+
133
+ deleteUser() {
134
+ this.dialog.confirmation({
135
+ title: "Delete user",
136
+ text: "Are you sure you want to delete user?",
137
+ confirmText: "Yes",
138
+ cancelText: "No"
139
+ })
140
+ .then(({ isConfirmed }) => {
141
+ if (isConfirmed) {
142
+ this.http.delete(this.url.lesli("/users/:id", this.user.id)).then(result => {
143
+ this.msg.success(I18n.t("core.users.messages_success_operation"))
144
+ //this.url.go("/administration/users")
145
+ }).catch(error => {
146
+ this.msg.danger(I18n.t("core.shared.messages_danger_internal_error"))
147
+ })
148
+ }
149
+ })
150
+ },
151
+
152
+ getRoles() {
153
+ this.http.get(this.url.lesli("users/:id/roles", this.user.id)).then(result => {
154
+ this.roles = result
155
+ }).catch(error => {
156
+ console.log(error)
157
+ })
158
+ },
159
+
160
+ postRole(role) {
161
+ this.http.post(this.url.lesli('users/:id/roles', this.user.id), {
162
+ user_role: {
163
+ id: role.id
164
+ }
165
+ }).then(result => {
166
+ this.msg.success(I18n.t("core.users.messages_success_operation"))
167
+ }).catch(error => {
168
+ this.msg.danger(I18n.t("core.shared.messages_danger_internal_error"))
169
+ })
170
+ },
171
+
172
+ deleteRole(role) {
173
+ this.http.delete(this.url.lesli('users/:user_id/roles/:role_id', {
174
+ user_id: this.user.id,
175
+ role_id: role.id
176
+ })).then(result => {
177
+ this.msg.success(I18n.t("core.users.messages_success_operation"))
178
+ }).catch(error => {
179
+ this.msg.danger(I18n.t("core.shared.messages_danger_internal_error"))
180
+ })
181
+ },
182
+
183
+ doRequestPassword() {
184
+ this.http.post(this.url.lesli("users/:id/requestpassword", this.user.id)).then(result => {
185
+ this.msg.success(I18n.t("core.users.messages_success_operation"))
186
+ }).catch(error => {
187
+ this.msg.danger(I18n.t("core.shared.messages_danger_internal_error"))
188
+ })
189
+ },
190
+
191
+ doPasswordReset() {
192
+ this.http.post(this.url.lesli("users/:id/passwordreset", this.user.id)).then(result => {
193
+ this.msg.success(I18n.t("core.users.messages_success_operation"))
194
+ }).catch(error => {
195
+ this.msg.danger(I18n.t("core.shared.messages_danger_internal_error"))
196
+ })
197
+ },
198
+
199
+ doLogout() {
200
+ this.http.post(this.url.lesli("users/:id/logout", this.user.id)).then(result => {
201
+ this.msg.success(I18n.t("core.users.messages_success_operation"))
202
+ }).catch(error => {
203
+ this.msg.danger(I18n.t("core.shared.messages_danger_internal_error"))
204
+ })
205
+ },
206
+
207
+ doRevokeAccess() {
208
+ this.http.post(this.url.lesli("users/:id/revokeaccess", this.user.id)).then(result => {
209
+ this.msg.success(I18n.t("core.users.messages_success_operation"))
210
+ }).catch(error => {
211
+ this.msg.danger(I18n.t("core.shared.messages_danger_internal_error"))
212
+ })
213
+ },
214
+
215
+ fetchSessions() {
216
+ if (!this.sessions.length > 0) {
217
+ this.getSessions()
218
+ }
219
+ },
220
+
221
+ getSessions() {
222
+ this.http.get(this.url.lesli("users/:id/sessions", this.user.id )).then(result => {
223
+ this.sessions.pagination = result.pagination
224
+ this.sessions.records = result.records
225
+ }).catch(error => {
226
+ this.msg.danger(I18n.t("core.shared.messages_danger_internal_error"))
227
+ }).finally(() => {
228
+ this.loading = false
229
+ })
230
+ },
231
+
232
+ deleteSession(user_session_id){
233
+ this.dialog.confirmation({
234
+ title: "Close session",
235
+ text: 'Are you sure you want to close this session',
236
+ confirmText: "Yes",
237
+ cancelText: "No"
238
+ })
239
+ .then(({ isConfirmed }) => {
240
+ if (isConfirmed) {
241
+ this.http.delete(this.url.lesli("users/:id/sessions/:session_id", {
242
+ id: this.user.id,
243
+ session_id: user_session_id
244
+ })).then(result => {
245
+ this.msg.success(I18n.t("core.users.messages_success_operation"))
246
+ }).catch(error => {
247
+ this.msg.danger(I18n.t("core.shared.messages_danger_internal_error"))
248
+ })
249
+ this.fetchSessions()
250
+ }
251
+ })
252
+ },
253
+
254
+ postLanguage() {
255
+ this.http.post(this.url.lesli('users/:id/settings', this.user.id), {
256
+ user_setting: {
257
+ name: 'locale',
258
+ value: this.user.locale.value
259
+ }
260
+ }).then(result => {
261
+ this.msg.success(I18n.t("core.users.messages_success_operation"))
262
+ // TODO: Only if current_user changed his own language
263
+ // reload the page so the user can work with the new language
264
+ // setTimeout(() => window.location.reload(), 1000)
265
+ }).catch(error => {
266
+ this.msg.danger(I18n.t("core.shared.messages_danger_internal_error"))
267
+ })
268
+ },
269
+
270
+ getOptions() {
271
+ this.http.get(this.url.lesli("users/options")).then(result => {
272
+ this.options.salutations = result.salutations
273
+
274
+ this.options.locales = Object.keys(result.locales).map(key => {
275
+ return {label: result.locales[key], value: key}
276
+ })
277
+ }).catch(error => {
278
+ this.msg.danger(I18n.t("core.shared.messages_danger_internal_error"))
279
+ })
280
+ },
281
+ }
282
+ })
283
+
284
+
285
+
286
+
287
+ /*
288
+
289
+
290
+
291
+ updatePassword() {
292
+ this.http.put("/", {
293
+ user: {
294
+ password: this.user.password,
295
+ password_confirmation: this.user.password_confirmation
296
+ }
297
+ }).then(result => {
298
+ this.msg.success(I18n.t("core.users.messages_success_operation"))
299
+ this.user.password = ""
300
+ this.user.password_confirmation = ""
301
+ }).catch(error => {
302
+ this.msg.danger(I18n.t("core.shared.messages_danger_internal_error"))
303
+ })
304
+ },
305
+
306
+ // This action is used to change the user status active or inactive
307
+ putUserStatus(){
308
+ this.dialog.confirmation({
309
+ title: "Change status",
310
+ text: "Are you sure you want to change the status of this user?",
311
+ confirmText: "Yes",
312
+ cancelText: "No"
313
+ })
314
+ .then(({ isConfirmed }) => {
315
+ if (isConfirmed) {
316
+ this.http.patch(this.url.lesli('users/:id', this.user.id), {
317
+ user: {
318
+ active: this.user.active
319
+ }
320
+ }).then(result => {
321
+ this.msg.success(I18n.t("core.users.messages_success_operation"))
322
+ }) .catch(error => {
323
+ this.msg.danger(I18n.t("core.shared.messages_danger_internal_error"))
324
+ })
325
+ } else {
326
+ this.user.active = !this.user.active
327
+ }
328
+ })
329
+ },
330
+
331
+ */
@@ -113,7 +113,7 @@ export const useUsers = defineStore("administration.users", {
113
113
 
114
114
  this.http.get(
115
115
  this.url
116
- .lesli("users")
116
+ .admin("users")
117
117
  .search(this.search_string)
118
118
  .paginate(this.index.pagination.page, this.filters.per_page)
119
119
  .filter(query_filters)
@@ -128,6 +128,31 @@ export const useUsers = defineStore("administration.users", {
128
128
  })
129
129
  },
130
130
 
131
+ getUser(id=null) {
132
+
133
+ // get the profile by default
134
+ let url = this.url.lesli("profile")
135
+
136
+ // get an specifick user if id is provided
137
+ if (id) { url = this.url.lesli("users/:id", id) }
138
+
139
+ this.http.get(url).then(result => {
140
+ this.user = result
141
+ this.user.password = ""
142
+ this.user.password_confirmation = ""
143
+
144
+ this.language = result.locale ? result.locale.value : this.language
145
+
146
+ // Backend should return the list of roles ordered by object level permission
147
+ this.role_names = result.roles[0].name
148
+
149
+ }).catch(error => {
150
+ this.msg.danger(I18n.t("core.shared.messages_danger_internal_error"))
151
+ }).finally(() => {
152
+ this.loading = false
153
+ })
154
+ },
155
+
131
156
  postUsers() {
132
157
  return this.http.post(this.url.admin("users"), {
133
158
  user: this.user
data/readme.md CHANGED
@@ -6,7 +6,7 @@
6
6
  <hr/>
7
7
  <p align="center">
8
8
  <a target="blank" href="https://rubygems.org/gems/lesli_admin">
9
- <img src="https://badge.fury.io/rb/lesli_admin.svg" alt="Gem Version" height="18">
9
+ <img src="https://badge.fury.io/rb/lesli_admin.svg" alt="Gem Version" height="24">
10
10
  </a>
11
11
  </p>
12
12
  <hr/>
@@ -32,12 +32,12 @@ end
32
32
 
33
33
 
34
34
  ### Documentation
35
- * [Roadmap](./docs/roadmap.md)
35
+ * [website](https://www.lesli.dev/admin/)
36
36
  * [database](./docs/database.md)
37
37
  * [documentation](https://www.lesli.dev/documentation/)
38
38
 
39
39
 
40
- ### Get in touch
40
+ ### Get in touch with Lesli
41
41
 
42
42
  * [Website: https://www.lesli.tech](https://www.lesli.tech)
43
43
  * [Email: hello@lesli.tech](hello@lesli.tech)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lesli_admin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - The Lesli Development Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-10-09 00:00:00.000000000 Z
11
+ date: 2023-11-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 7.0.6
27
+ - !ruby/object:Gem::Dependency
28
+ name: lesli
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '5'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '5'
27
41
  description: Administration area for the Lesli Framework
28
42
  email:
29
43
  - hello@lesli.tech
@@ -35,7 +49,6 @@ files:
35
49
  - app/assets/config/lesli_admin_manifest.js
36
50
  - app/assets/images/lesli_admin/admin-logo.svg
37
51
  - app/assets/javascripts/lesli_admin/application.js
38
- - app/assets/javascripts/lesli_admin/translations.js
39
52
  - app/assets/stylesheets/lesli_admin/application.scss
40
53
  - app/assets/stylesheets/lesli_admin/users.scss
41
54
  - app/controllers/lesli_admin/accounts_controller.rb
@@ -50,6 +63,7 @@ files:
50
63
  - app/mailers/lesli_admin/application_mailer.rb
51
64
  - app/models/lesli_admin/account.rb
52
65
  - app/models/lesli_admin/application_record.rb
66
+ - app/services/lesli_admin/user_service.rb
53
67
  - app/views/layouts/lesli_admin/application.html.erb
54
68
  - app/views/lesli_admin/accounts/_account.html.erb
55
69
  - app/views/lesli_admin/accounts/_form.html.erb
@@ -64,9 +78,6 @@ files:
64
78
  - app/views/lesli_admin/dashboards/new.html.erb
65
79
  - app/views/lesli_admin/dashboards/show.html.erb
66
80
  - app/views/lesli_admin/partials/_engine-navigation.html.erb
67
- - app/views/lesli_admin/profiles/edit.html.erb
68
- - app/views/lesli_admin/profiles/index.html.erb
69
- - app/views/lesli_admin/profiles/new.html.erb
70
81
  - app/views/lesli_admin/profiles/show.html.erb
71
82
  - app/views/lesli_admin/users/edit.html.erb
72
83
  - app/views/lesli_admin/users/index.html.erb
@@ -75,6 +86,7 @@ files:
75
86
  - config/locales/translations.en.yml
76
87
  - config/locales/translations.es.yml
77
88
  - config/routes.rb
89
+ - db/migrate/0101000110_create_lesli_admin_accounts.rb
78
90
  - lib/lesli_admin.rb
79
91
  - lib/lesli_admin/engine.rb
80
92
  - lib/lesli_admin/version.rb
@@ -101,6 +113,7 @@ files:
101
113
  - lib/vue/stores/account_settings.js
102
114
  - lib/vue/stores/roles.js
103
115
  - lib/vue/stores/translations.json
116
+ - lib/vue/stores/user.js
104
117
  - lib/vue/stores/users.js
105
118
  - readme.md
106
119
  homepage: https://www.lesli.dev/