lesli_admin 0.2.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/config/lesli_admin_manifest.js +0 -1
  3. data/app/assets/javascripts/lesli_admin/application.js +362 -831
  4. data/app/assets/stylesheets/lesli_admin/application.scss +2 -1
  5. data/app/controllers/lesli_admin/accounts_controller.rb +3 -5
  6. data/app/controllers/lesli_admin/dashboard/components_controller.rb +60 -0
  7. data/app/controllers/lesli_admin/dashboards_controller.rb +26 -50
  8. data/app/models/lesli_admin/account.rb +7 -29
  9. data/app/{controllers/lesli_admin/profiles_controller.rb → models/lesli_admin/dashboard/component.rb} +13 -19
  10. data/app/models/lesli_admin/dashboard.rb +58 -0
  11. data/app/{controllers/lesli_admin/users_controller.rb → services/lesli_admin/account_service.rb} +6 -20
  12. data/app/views/lesli_admin/dashboards/edit.html.erb +29 -7
  13. data/app/views/lesli_admin/dashboards/index.html.erb +29 -11
  14. data/app/views/lesli_admin/dashboards/new.html.erb +29 -6
  15. data/app/views/lesli_admin/dashboards/show.html.erb +31 -0
  16. data/app/views/lesli_admin/partials/_engine-navigation.html.erb +0 -1
  17. data/config/locales/translations.en.yml +29 -4
  18. data/config/locales/translations.es.yml +29 -4
  19. data/config/routes.rb +46 -5
  20. data/db/migrate/0101000110_create_lesli_admin_accounts.rb +42 -0
  21. data/db/migrate/0101050110_create_lesli_admin_dashboards.rb +51 -0
  22. data/db/migrate/0101050210_create_lesli_admin_dashboard_components.rb +53 -0
  23. data/lib/lesli_admin/engine.rb +1 -0
  24. data/lib/lesli_admin/version.rb +2 -2
  25. data/lib/vue/application.js +28 -15
  26. data/lib/vue/apps/account/components/{address-form.vue → form-address.vue} +27 -42
  27. data/lib/vue/apps/account/components/form-contact.vue +122 -0
  28. data/lib/vue/apps/account/components/form-information.vue +13 -31
  29. data/lib/vue/apps/account/show.vue +14 -13
  30. data/lib/vue/apps/{users/components/integrations-information.vue → dashboards/components/lesli-version.vue} +36 -26
  31. data/lib/vue/apps/{profile/components/change-email.vue → dashboards/show.vue} +9 -6
  32. data/lib/vue/stores/translations.json +62 -10
  33. data/readme.md +3 -3
  34. metadata +30 -30
  35. data/app/assets/javascripts/lesli_admin/translations.js +0 -2291
  36. data/app/views/lesli_admin/dashboards/_dashboard.html.erb +0 -2
  37. data/app/views/lesli_admin/dashboards/_form.html.erb +0 -17
  38. data/app/views/lesli_admin/profiles/edit.html.erb +0 -10
  39. data/app/views/lesli_admin/profiles/index.html.erb +0 -14
  40. data/app/views/lesli_admin/profiles/new.html.erb +0 -9
  41. data/lib/vue/apps/account/components/contact-form.vue +0 -162
  42. data/lib/vue/apps/dashboard/show.vue +0 -31
  43. data/lib/vue/apps/profile/components/subscriptions.vue +0 -94
  44. data/lib/vue/apps/profile/show.vue +0 -148
  45. data/lib/vue/apps/users/components/information-card.vue +0 -116
  46. data/lib/vue/apps/users/components/information-form.vue +0 -177
  47. data/lib/vue/apps/users/components/management-roles.vue +0 -109
  48. data/lib/vue/apps/users/components/management-security.vue +0 -113
  49. data/lib/vue/apps/users/components/management-sessions.vue +0 -106
  50. data/lib/vue/apps/users/components/management-settings.vue +0 -94
  51. data/lib/vue/apps/users/index.vue +0 -207
  52. data/lib/vue/apps/users/new.vue +0 -181
  53. data/lib/vue/apps/users/show.vue +0 -116
  54. data/lib/vue/stores/users.js +0 -150
@@ -1,207 +0,0 @@
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: {
58
- view_text_title_users: i18n.t('lesli_admin.users.title_users')
59
- },
60
- shared: I18n.t("core.shared")
61
- }
62
- }
63
-
64
-
65
- // ·
66
- const columns = [{
67
- field: "id",
68
- label: "ID",
69
- sort: true
70
- }, {
71
- field: "name",
72
- label: translations.core.users.view_table_header_name,
73
- sort: true
74
- }, {
75
- field: "email",
76
- label: translations.core.users.view_table_header_email,
77
- sort: true
78
- }, {
79
- field: "rolenames",
80
- label: translations.core.users.view_table_header_role,
81
- sort: true
82
- }, {
83
- field: "active",
84
- label: translations.core.users.view_table_header_status,
85
- sort: true,
86
- custom: true
87
- }, {
88
- field: "current_sign_in_at_string",
89
- label: translations.core.users.view_table_header_last_sign_in,
90
- sort: true
91
- }, {
92
- field: "last_action_performed_at_string",
93
- label: translations.core.users.view_text_last_activity_at,
94
- sort: true
95
- }]
96
-
97
-
98
- // ·
99
- const selection = ref()
100
-
101
-
102
- // · defining props
103
- const props = defineProps({
104
- appMountPath: {
105
- type: String,
106
- required: false,
107
- default: "lesli/users",
108
- },
109
- defaultRole: {
110
- type: String,
111
- required: false,
112
- default: "",
113
- }
114
- })
115
-
116
-
117
- // · initializing
118
- onMounted(() => {
119
- storeUsers.fetchUsers()
120
- i18n.t("lesli_admin.users.title_users")
121
- })
122
-
123
-
124
- //
125
- function showUser(user) {
126
- router.push(url.root(props.appMountPath+`/${user.id}`).s)
127
- }
128
- </script>
129
- <template>
130
- <lesli-application-container>
131
- <lesli-header :title="translations.core.users.view_text_title_users + ' (' +storeUsers.index.pagination.total+ ')' ">
132
- <lesli-button icon="add" :to="url.root(props.appMountPath+`/new`)">
133
- {{ translations.core.users.view_text_add_user }}
134
- </lesli-button>
135
- <lesli-button
136
- icon="refresh"
137
- :loading="storeUsers.loading"
138
- @click="storeUsers.getUsers()">
139
- {{ translations.core.shared.view_text_btn_reload }}
140
- </lesli-button>
141
- </lesli-header>
142
-
143
- <lesli-toolbar>
144
- </lesli-toolbar>
145
- <!--
146
- <lesli-toolbar
147
- @search="storeUsers.search"
148
- :search-placeholder="translations.core.users.view_toolbar_filter_placeholder_search">
149
- <lesli-select :options="[{
150
- label: translations.core.users.view_toolbar_filter_placeholder_all_users,
151
- value: null
152
- }, {
153
- label: translations.core.users.view_toolbar_filter_placeholder_active_users,
154
- value: 'active'
155
- }, {
156
- label: translations.core.users.view_toolbar_filter_placeholder_inactive_users,
157
- value: 'inactive'
158
- }]"
159
- v-model="storeUsers.filters.status"
160
- @change="storeUsers.fetchIndex()">
161
- </lesli-select>
162
- <lesli-select :options="storeUsers.roles_options"
163
- v-model="storeUsers.filters.role"
164
- @change="storeUsers.fetchIndex()">
165
- </lesli-select>
166
- </lesli-toolbar>
167
- -->
168
-
169
- <lesli-table
170
- :loading="storeUsers.loading"
171
- :columns="columns"
172
- :records="storeUsers.index.records"
173
- :pagination="storeUsers.index.pagination"
174
- :link="(user) => url.admin('users/:id', user.id)"
175
- @paginate="storeUsers.paginateIndex"
176
- @sort="storeUsers.sortIndex">
177
-
178
- <template #active="{ value }">
179
- <span class="tag is-success" v-if="value">
180
- {{ translations.core.shared.view_text_active }}
181
- </span>
182
- <span class="tag is-warning" v-if="!value">
183
- {{ translations.core.shared.view_text_inactive }}
184
- </span>
185
- </template>
186
-
187
- <template #options="{ record, value }">
188
- <a class="dropdown-item" @click="storeUsers.doLogout(record.id)">
189
- <span class="material-icons">
190
- logout
191
- </span>
192
- <span>
193
- {{ translations.core.users.view_btn_logout }}
194
- </span>
195
- </a>
196
- <a class="dropdown-item" @click="storeUsers.doLock(record.id)">
197
- <span class="material-icons">
198
- lock
199
- </span>
200
- <span>
201
- {{ translations.core.users.view_btn_revoke_access }}
202
- </span>
203
- </a>
204
- </template>
205
- </lesli-table>
206
- </lesli-application-container>
207
- </template>
@@ -1,181 +0,0 @@
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 Development Platform.
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 { onMounted, inject } from "vue"
36
- import { useRouter, useRoute } from 'vue-router'
37
-
38
-
39
- // · import lesli stores
40
- import { useUsers } from "LesliAdmin/stores/users"
41
- import { useRoles } from "LesliAdmin/stores/roles"
42
-
43
-
44
- // · implement stores
45
- const storeUsers = useUsers()
46
- const storeRoles = useRoles()
47
- const router = useRouter()
48
- const route = useRoute()
49
-
50
-
51
- // · implement composables
52
- const url = inject("url")
53
- const msg = inject("msg")
54
-
55
-
56
- // · translations
57
- const translations = {
58
- users: I18n.t("core.users"),
59
- shared: I18n.t("core.shared")
60
- }
61
-
62
-
63
- // ·
64
- const onCreate = () => {
65
- storeUsers.postUsers().then(result => {
66
- storeUsers.user = {}
67
- msg.success(I18n.t("core.users.messages_success_operation"))
68
- router.push(url.admin("users/:id", result.id).toString())
69
- }).catch(error => {
70
- msg.danger(I18n.t("core.shared.messages_danger_internal_error"))
71
- })
72
- }
73
-
74
-
75
- // ·
76
- onMounted(() => {
77
- console.log("works")
78
- storeRoles.fetchList()
79
- })
80
- </script>
81
- <template>
82
- <lesli-application>
83
- <lesli-header title="Create User">
84
- <lesli-button icon="list" :to="url.admin('users')">
85
- All users
86
- </lesli-button>
87
- </lesli-header>
88
-
89
- <lesli-form @submit="onCreate()">
90
- <p>User information</p>
91
- <div class="field is-horizontal">
92
- <div class="field-label is-normal">
93
- <label class="label">
94
- {{translations.shared.view_text_email}}
95
- <span class="is-danger">*</span>
96
- </label>
97
- </div>
98
- <div class="field-body">
99
- <div class="field">
100
- <div class="control">
101
- <input name="user_email" v-model="storeUsers.user.email" required="required" type="email" class="input">
102
- </div>
103
- </div>
104
- </div>
105
- </div>
106
-
107
- <div class="field is-horizontal">
108
- <div class="field-label is-normal">
109
- <label class="label">
110
- {{ translations.shared.view_text_first_name }}
111
- </label>
112
- </div>
113
- <div class="field-body">
114
- <div class="field">
115
- <div class="control">
116
- <input name="first_name" v-model="storeUsers.user.first_name" type="text" class="input">
117
- </div>
118
- </div>
119
- </div>
120
- </div>
121
-
122
- <div class="field is-horizontal">
123
- <div class="field-label is-normal">
124
- <label class="label"> {{ translations.shared.view_text_last_name }} </label>
125
- </div>
126
- <div class="field-body">
127
- <div class="field">
128
- <div class="control">
129
- <input name="last_name" v-model="storeUsers.user.last_name" class="input">
130
- </div>
131
- </div>
132
- </div>
133
- </div>
134
-
135
- <div class="field is-horizontal">
136
- <div class="field-label is-normal">
137
- <label class="label"> {{ translations.shared.view_text_telephone }} </label>
138
- </div>
139
- <div class="field-body">
140
- <div class="field">
141
- <div class="control">
142
- <input name="user_number" v-model="storeUsers.user.telephone" class="input">
143
- </div>
144
- </div>
145
- </div>
146
- </div>
147
-
148
- <div class="field is-horizontal">
149
- <div class="field-label is-normal">
150
- <label class="label"> {{ translations.users.view_text_role }} </label>
151
- </div>
152
- <div class="field-body">
153
- <div class="field is-narrow">
154
- <div class="control">
155
- <div class="select is-fullwidth">
156
- <lesli-select
157
- :options="storeRoles.listOptions"
158
- v-model="storeUsers.user.roles_id">
159
- </lesli-select>
160
- </div>
161
- </div>
162
- </div>
163
- </div>
164
- </div>
165
-
166
- <div class="field is-horizontal">
167
- <div class="field-label is-normal">
168
- </div>
169
- <div class="field-body">
170
- <div class="field">
171
- <div class="control">
172
- <lesli-button icon="save">
173
- {{ translations.shared.view_btn_save }}
174
- </lesli-button>
175
- </div>
176
- </div>
177
- </div>
178
- </div>
179
- </lesli-form>
180
- </lesli-application>
181
- </template>
@@ -1,116 +0,0 @@
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, onMounted } from "vue"
36
- import { useRouter, useRoute } from 'vue-router'
37
-
38
-
39
- // · import lesli stores
40
- import { useUser } from "Lesli/stores/user"
41
-
42
-
43
- // · implement stores
44
- const storeUser = useUser()
45
- const router = useRouter()
46
- const route = useRoute()
47
-
48
-
49
- // · import profile components
50
- import informationCard from "LesliAdmin/apps/users/components/information-card.vue"
51
- import informationForm from "LesliAdmin/apps/users/components/information-form.vue"
52
- /*
53
- import informationForm from "CloudAdmin/apps/users/components/information-form.vue"
54
-
55
- import managementRoles from "CloudAdmin/apps/users/components/management-roles.vue"
56
- import managementSession from "CloudAdmin/apps/users/components/management-sessions.vue"
57
- import managementSecurity from "CloudAdmin/apps/users/components/management-security.vue"
58
- import managementSettings from "CloudAdmin/apps/users/components/management-settings.vue"
59
- */
60
-
61
-
62
-
63
-
64
- // · translations
65
- const translations = {
66
- core: {
67
- roles: I18n.t("core.roles"),
68
- users: I18n.t("core.users"),
69
- shared: I18n.t("core.shared")
70
- }
71
- }
72
-
73
-
74
- // ·
75
- const tab = ref(0)
76
-
77
-
78
- // · initializing
79
- onMounted(() => {
80
- // storeUser.$reset()
81
- // storeUser.getOptions()
82
- storeUser.getUser(route.params?.id)
83
- })
84
- </script>
85
- <template>
86
- <lesli-application-container>
87
- <information-card></information-card>
88
- <lesli-tabs v-model="tab">
89
- <lesli-tab-item icon="info_outline" title="Information">
90
- <information-form></information-form>
91
- </lesli-tab-item>
92
- </lesli-tabs>
93
- </lesli-application-container>
94
- <!--
95
- <application-component>
96
- <information-card></information-card>
97
- <lesli-tabs v-model="tab" v-if="storeUser.user.id">
98
- <lesli-tab-item icon="info_outline" :title="translations.core.users.view_tab_title_information">
99
- <information-form></information-form>
100
- </lesli-tab-item>
101
- <lesli-tab-item icon="security" :title="translations.core.users.view_tab_title_roles_and_privileges">
102
- <management-roles></management-roles>
103
- </lesli-tab-item>
104
- <lesli-tab-item icon="lock_outline" :title="translations.core.users.view_tab_title_security || 'Security'">
105
- <management-security></management-security>
106
- </lesli-tab-item>
107
- <lesli-tab-item icon="devices" :title="translations.core.users.view_tab_title_session || 'Sessions'" paddingless>
108
- <management-session></management-session>
109
- </lesli-tab-item>
110
- <lesli-tab-item icon="settings" :title="translations.core.users.view_tab_title_settings">
111
- <management-settings></management-settings>
112
- </lesli-tab-item>
113
- </lesli-tabs>
114
- </application-component>
115
- -->
116
- </template>
@@ -1,150 +0,0 @@
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
- // · translations
37
- const translations = {
38
- core: {
39
- roles: I18n.t("core.roles"),
40
- users: I18n.t("core.users"),
41
- shared: I18n.t("core.shared")
42
- }
43
- }
44
-
45
- // ·
46
- export const useUsers = defineStore("administration.users", {
47
- state: () => {
48
- return {
49
- loading: false,
50
- search: "",
51
- list: [],
52
- order: {
53
- column: "id",
54
- direction: "desc"
55
- },
56
- index: {
57
- pagination: {},
58
- records: []
59
- },
60
- filters :{
61
- per_page: 15,
62
- role: null,
63
- status: 'active'
64
- },
65
- roles_options: [],
66
-
67
- user: {
68
- roles_id: null,
69
- email: null,
70
- first_name: null,
71
- last_name: null,
72
- telephone: null,
73
- }
74
- }
75
- },
76
- actions: {
77
-
78
- search(search_string) {
79
- this.index.pagination.page = 1
80
- this.search_string = search_string
81
- this.loading = true
82
- this.getUsers()
83
- },
84
-
85
- paginateIndex(page) {
86
- this.index.pagination.page = page
87
- this.getUsers()
88
- },
89
-
90
- sortIndex(column, direction) {
91
- this.order.column = column
92
- this.order.direction = direction
93
- this.getUsers()
94
- },
95
-
96
- fetchUsers() {
97
-
98
- if (!this.index.pagination?.results > 0) {
99
- this.loading = true
100
- this.getUsers()
101
- }
102
-
103
- },
104
-
105
- getUsers() {
106
-
107
- const query_filters = {}
108
-
109
- //Format filters to send them in the query string
110
- for (const [key, value] of Object.entries(this.filters)) {
111
- //query_filters[key] = [value]
112
- }
113
-
114
- this.http.get(
115
- this.url
116
- .lesli("users")
117
- .search(this.search_string)
118
- .paginate(this.index.pagination.page, this.filters.per_page)
119
- .filter(query_filters)
120
- .order(this.order.column, this.order.direction)
121
- ).then(result => {
122
- this.index = result
123
- this.search_string=""
124
- }).catch(error => {
125
- this.msg.danger(I18n.t("core.shared.messages_danger_internal_error"))
126
- }).finally(() => {
127
- this.loading = false
128
- })
129
- },
130
-
131
- postUsers() {
132
- return this.http.post(this.url.admin("users"), {
133
- user: this.user
134
- })
135
- },
136
-
137
- fetchList() {
138
- this.loading = true
139
- return this.http.get(this.url.admin("users/list")).then(response => {
140
- //this.records = response
141
- this.list = response
142
- }).catch(error => {
143
-
144
- }).finally(() => {
145
- this.loading = false
146
- })
147
- }
148
-
149
- }
150
- })