lesli_shield 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +7 -0
  2. data/Rakefile +5 -0
  3. data/app/assets/config/lesli_shield_manifest.js +47 -0
  4. data/app/assets/images/lesli_shield/shield-logo.svg +1 -0
  5. data/app/assets/javascripts/lesli_shield/application.js +4428 -0
  6. data/app/assets/javascripts/lesli_shield/confirmations.js +60 -0
  7. data/app/assets/javascripts/lesli_shield/passwords.js +712 -0
  8. data/app/assets/javascripts/lesli_shield/registrations.js +712 -0
  9. data/app/assets/javascripts/lesli_shield/sessions.js +712 -0
  10. data/app/assets/stylesheets/lesli_shield/application.css +4 -0
  11. data/app/assets/stylesheets/lesli_shield/confirmations.css +19219 -0
  12. data/app/assets/stylesheets/lesli_shield/passwords.css +19202 -0
  13. data/app/assets/stylesheets/lesli_shield/registrations.css +19588 -0
  14. data/app/assets/stylesheets/lesli_shield/sessions.css +19588 -0
  15. data/app/controllers/lesli_shield/application_controller.rb +4 -0
  16. data/app/controllers/lesli_shield/dashboard/components_controller.rb +60 -0
  17. data/app/controllers/lesli_shield/dashboards_controller.rb +4 -0
  18. data/app/controllers/users/confirmations_controller.rb +66 -0
  19. data/app/controllers/users/omniauth_callbacks_controller.rb +30 -0
  20. data/app/controllers/users/passwords_controller.rb +71 -0
  21. data/app/controllers/users/registrations_controller.rb +141 -0
  22. data/app/controllers/users/sessions_controller.rb +141 -0
  23. data/app/controllers/users/unlocks_controller.rb +30 -0
  24. data/app/helpers/lesli_shield/application_helper.rb +4 -0
  25. data/app/helpers/lesli_shield/dashboards_helper.rb +4 -0
  26. data/app/jobs/lesli_shield/application_job.rb +4 -0
  27. data/app/mailers/lesli_shield/application_mailer.rb +6 -0
  28. data/app/models/lesli_shield/application_record.rb +5 -0
  29. data/app/models/lesli_shield/dashboard/component.rb +18 -0
  30. data/app/models/lesli_shield/dashboard.rb +31 -0
  31. data/app/views/devise/confirmations/new.html.erb +2 -0
  32. data/app/views/devise/confirmations/show.html.erb +63 -0
  33. data/app/views/devise/mailer/confirmation_instructions.html.erb +5 -0
  34. data/app/views/devise/mailer/email_changed.html.erb +7 -0
  35. data/app/views/devise/mailer/password_change.html.erb +3 -0
  36. data/app/views/devise/mailer/reset_password_instructions.html.erb +8 -0
  37. data/app/views/devise/mailer/unlock_instructions.html.erb +7 -0
  38. data/app/views/devise/passwords/edit.html.erb +79 -0
  39. data/app/views/devise/passwords/new.html.erb +75 -0
  40. data/app/views/devise/registrations/edit.html.erb +43 -0
  41. data/app/views/devise/registrations/new.html.erb +151 -0
  42. data/app/views/devise/sessions/new.html.erb +114 -0
  43. data/app/views/devise/shared/_demo.html.erb +7 -0
  44. data/app/views/devise/shared/_error_messages.html.erb +15 -0
  45. data/app/views/devise/shared/_links.html.erb +96 -0
  46. data/app/views/devise/unlocks/new.html.erb +16 -0
  47. data/app/views/layouts/lesli_shield/application.html.erb +15 -0
  48. data/app/views/lesli_shield/dashboards/edit.html.erb +1 -0
  49. data/app/views/lesli_shield/dashboards/index.html.erb +1 -0
  50. data/app/views/lesli_shield/dashboards/new.html.erb +1 -0
  51. data/app/views/lesli_shield/dashboards/show.html.erb +1 -0
  52. data/config/initializers/devise.rb +336 -0
  53. data/config/locales/translations.en.yml +21 -0
  54. data/config/locales/translations.es.yml +21 -0
  55. data/config/locales/translations.fr.yml +21 -0
  56. data/config/locales/translations.it.yml +21 -0
  57. data/config/locales/translations.pt.yml +21 -0
  58. data/config/routes.rb +57 -0
  59. data/db/migrate/v1/0801000110_create_lesli_shield_accounts.rb +42 -0
  60. data/db/migrate/v1/0801050110_create_lesli_shield_dashboards.rb +51 -0
  61. data/db/migrate/v1/0801050210_create_lesli_shield_dashboard_components.rb +53 -0
  62. data/lib/lesli_shield/engine.rb +54 -0
  63. data/lib/lesli_shield/routing.rb +26 -0
  64. data/lib/lesli_shield/version.rb +4 -0
  65. data/lib/lesli_shield.rb +6 -0
  66. data/lib/scss/application.scss +0 -0
  67. data/lib/scss/confirmations.scss +58 -0
  68. data/lib/scss/devise/oauth.scss +34 -0
  69. data/lib/scss/passwords.scss +33 -0
  70. data/lib/scss/registrations.scss +35 -0
  71. data/lib/scss/sessions.scss +35 -0
  72. data/lib/tasks/lesli_shield_tasks.rake +4 -0
  73. data/lib/vue/application.js +76 -0
  74. data/lib/vue/apps/dashboards/components/engine-version.vue +71 -0
  75. data/lib/vue/confirmations.js +33 -0
  76. data/lib/vue/passwords.js +137 -0
  77. data/lib/vue/registrations.js +144 -0
  78. data/lib/vue/sessions.js +148 -0
  79. data/lib/vue/stores/translations.json +152 -0
  80. data/license +674 -0
  81. data/readme.md +71 -0
  82. metadata +168 -0
@@ -0,0 +1,137 @@
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 SaaS Development Framework.
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
+
35
+
36
+ // ·
37
+ import application from "Lesli/vue/public"
38
+
39
+
40
+ // ·
41
+ application({
42
+
43
+ data() {
44
+ return {
45
+ loading: false,
46
+ translations: {
47
+ main: {}
48
+ },
49
+ sign_in: {
50
+ email: "",
51
+ password: ""
52
+ },
53
+ password_edit: {
54
+ new_password: "",
55
+ new_password_confirmation: ""
56
+ },
57
+ notification: {
58
+ message: "",
59
+ show: false,
60
+ type: ""
61
+ }
62
+ }
63
+ },
64
+ methods: {
65
+
66
+ postPasswordNew(event) {
67
+
68
+ this.notification.show = false
69
+
70
+ this.loading = true
71
+
72
+ event.preventDefault();
73
+
74
+ let data = {
75
+ user: {
76
+ email: this.sign_in.email.toLowerCase(),
77
+ password: this.sign_in.password
78
+ }
79
+ };
80
+
81
+ this.http.post("/password", data).then(response => {
82
+ this.showNotification("this.translations.main.notification_reset_password_instructions_sent", "success")
83
+ }).catch(error => {
84
+ this.showNotification(error.message)
85
+ }).finally(() => {
86
+ this.loading = false
87
+ })
88
+ },
89
+
90
+ putPasswordEdit(event) {
91
+
92
+ this.notification.show = false
93
+
94
+ this.loading = true
95
+
96
+ event.preventDefault();
97
+
98
+ // check if passwords match
99
+ if (this.password_edit.new_password != this.password_edit.new_password_confirmation) {
100
+ this.showNotification("this.translations.main.error_passwords_do_not_match", "danger")
101
+ return
102
+ }
103
+
104
+ var token=null
105
+
106
+ try {
107
+ token = Object.fromEntries(new URLSearchParams(window.location.search)).reset_password_token
108
+ } catch (error) {
109
+ token=null
110
+ }
111
+
112
+ this.http.put("/password", {
113
+ user: {
114
+ password: this.password_edit.new_password,
115
+ password_confirmation: this.password_edit.new_password_confirmation,
116
+ reset_password_token: token
117
+ }
118
+ }).then(response => {
119
+ this.showNotification("this.translations.main.notification_password_updated", "success")
120
+ //setTimeout(() => { this.url.go("/login") }, 2000)
121
+ }).catch(error => {
122
+ this.showNotification(error.message, "danger")
123
+ }).finally(() => {
124
+ this.loading = false
125
+ })
126
+
127
+ },
128
+
129
+ showNotification(message, type="danger"){
130
+ this.notification.message = message;
131
+ this.notification.type = "is-"+type;
132
+ this.notification.show = true;
133
+ }
134
+
135
+ }
136
+
137
+ })
@@ -0,0 +1,144 @@
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 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
+
34
+ // ·
35
+ import application from "Lesli/vue/public"
36
+
37
+
38
+ // ·
39
+ application({
40
+
41
+ data(){
42
+ return {
43
+ translations: {},
44
+ password_uppercase: 0,
45
+ password_symbol: 0,
46
+ password_number: 0,
47
+ telephone_code: "",
48
+ telephone_codes: null,
49
+ sign_up: {
50
+ email: "",
51
+ password: "",
52
+ password_confirmation: '',
53
+ // first_name: null,
54
+ // last_name: null,
55
+ // telephone: null,
56
+ },
57
+ progress_bar_active: false,
58
+ notification: {
59
+ show: false,
60
+ message: '',
61
+ type: 'is-danger'
62
+ }
63
+
64
+ }
65
+ },
66
+ mounted() {
67
+ this.$refs.email.focus()
68
+ },
69
+ methods: {
70
+
71
+ postRegistration(event) {
72
+
73
+ this.notification.show = false;
74
+
75
+ event.preventDefault();
76
+
77
+ const user = this.validateFields()
78
+
79
+ this.http.post(this.url.to(), user).then(response => {
80
+
81
+ //setTimeout(() => { this.url.go("/login") }, 5000)
82
+
83
+ }).catch((err)=>{
84
+ this.showNotification(err.message)
85
+ })
86
+
87
+ },
88
+
89
+ typing() {
90
+ this.notification.message= ""
91
+ this.notification.show= false
92
+ this.notification.type= "default"
93
+ this.verifyPasswords()
94
+ },
95
+
96
+ showNotification(message,type = "danger") {
97
+ this.notification.message = message
98
+ this.notification.type = type
99
+ this.notification.show = true
100
+ },
101
+
102
+ verifyPasswords() {
103
+
104
+ this.password_uppercase = 0
105
+ this.password_number = 0
106
+ this.password_symbol = 0
107
+
108
+ if (this.sign_up.password.length <= 0) {
109
+ return
110
+ }
111
+
112
+ if (this.sign_up.password.search(/[A-Z]/) < 0) {
113
+ this.password_uppercase = 1
114
+ } else {
115
+ this.password_uppercase = 2
116
+ }
117
+
118
+ if (this.sign_up.password.search(/[0-9]/) < 0) {
119
+ this.password_number = 1
120
+ } else {
121
+ this.password_number = 2
122
+ }
123
+
124
+ if (this.sign_up.password.search(/[!#$%&]/) < 0) {
125
+ this.password_symbol = 1
126
+ } else {
127
+ this.password_symbol = 2
128
+ }
129
+
130
+ },
131
+
132
+ validateFields() {
133
+
134
+ // · copy object without reference
135
+ const user = JSON.parse(JSON.stringify(this.sign_up))
136
+
137
+ if (user.password_confirmation == "") {
138
+ user.password_confirmation = user.password
139
+ }
140
+
141
+ return user
142
+ }
143
+ }
144
+ })
@@ -0,0 +1,148 @@
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 SaaS Development Framework.
20
+
21
+ Made with ♥ by LesliTech
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 application from "Lesli/vue/public"
35
+
36
+
37
+ // ·
38
+ application({
39
+
40
+ data(){
41
+ return {
42
+ loading: false,
43
+ sign_in: {
44
+ email: "",
45
+ password: ""
46
+ },
47
+ notification: {
48
+ message: "",
49
+ show: false,
50
+ type: "default"
51
+ },
52
+ errors: []
53
+ }
54
+ },
55
+ mounted() {
56
+ this.$refs?.email?.focus()
57
+
58
+ if (lesli_application_development) {
59
+ this.sign_in.email = "hello@lesli.tech"
60
+ this.sign_in.password = "Tardis2024$"
61
+ }
62
+ },
63
+ methods: {
64
+
65
+ togglePasswordInput() {
66
+ if (this.$refs.password.type === "password") {
67
+ this.$refs.password.type = "text";
68
+ } else {
69
+ this.$refs.password.type = "password";
70
+ }
71
+ },
72
+
73
+ validateEmail() {
74
+ if (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(this.sign_in.email)) {
75
+ console.log("error")
76
+ }
77
+ },
78
+
79
+ build_redirect_url(default_path = null) {
80
+
81
+ // redirect to the root of the domain by default
82
+ let redirect_url = "/"
83
+
84
+ try {
85
+
86
+ // search for a redirection route in the url params
87
+ redirect_url = Object.fromEntries(new URLSearchParams(window.location.search)).r
88
+
89
+ } catch (error) {
90
+
91
+ }
92
+
93
+ // redirect to the default path if:
94
+ // - there is no query params with redirection
95
+ if (!redirect_url && default_path) {
96
+ redirect_url = default_path
97
+ }
98
+
99
+ // redirect to the root if:
100
+ // - error parsing redirection route
101
+ // - there is no query params with redirection
102
+ if (!redirect_url) {
103
+ redirect_url = "/"
104
+ }
105
+
106
+ return redirect_url
107
+
108
+ },
109
+
110
+ postLogin(event) {
111
+
112
+ this.loading = true
113
+
114
+ event.preventDefault();
115
+
116
+ this.notification.show = false
117
+
118
+ let data = {
119
+ user: {
120
+ email: this.sign_in.email.toLowerCase(),
121
+ password: this.sign_in.password
122
+ }
123
+ };
124
+
125
+ this.http.post("/login", data).then(response => {
126
+ this.url.go(this.build_redirect_url(response.default_path))
127
+ }).catch(error => {
128
+ this.showNotification(error.message)
129
+ }).finally(() => {
130
+ this.loading = false
131
+ })
132
+
133
+ },
134
+
135
+ typing() {
136
+ this.notification.message= ""
137
+ this.notification.show= false
138
+ this.notification.type= "default"
139
+ },
140
+
141
+ showNotification(message, type="danger"){
142
+ this.notification.message = message;
143
+ this.notification.type = type;
144
+ this.notification.show = true;
145
+ }
146
+
147
+ }
148
+ })
@@ -0,0 +1,152 @@
1
+ {
2
+ "en": {
3
+ "lesli": {
4
+ "application": {
5
+ "navigation_logout": "Logout",
6
+ "navigation_my_profile": "My profile"
7
+ },
8
+ "dashboards": {
9
+ "column_default": "Default",
10
+ "column_name": "Name",
11
+ "title": "Dashboards",
12
+ "view_add_component": "Add component"
13
+ },
14
+ "shared": {
15
+ "button_add_new": "Add new",
16
+ "button_delete": "Delete",
17
+ "button_edit": "Edit",
18
+ "button_list": "List",
19
+ "button_reload": "Reload",
20
+ "button_save": "Save",
21
+ "button_settings": "Settings",
22
+ "button_show": "Show",
23
+ "toolbar_search": "Search...",
24
+ "view_discussions": "Discussions",
25
+ "view_files": "Files",
26
+ "view_quick_actions": "Quick actions",
27
+ "view_status_active": "Active",
28
+ "view_status_inactive": "Inactive"
29
+ }
30
+ }
31
+ },
32
+ "es": {
33
+ "lesli": {
34
+ "application": {
35
+ "navigation_logout": "Cerrar sesión",
36
+ "navigation_my_profile": "Mi perfil"
37
+ },
38
+ "dashboards": {
39
+ "column_default": "Default",
40
+ "column_name": "Nombre",
41
+ "title": "Dashboards",
42
+ "view_add_component": "Agregar componente"
43
+ },
44
+ "shared": {
45
+ "button_add_new": "Agregar nuevo",
46
+ "button_delete": "Eliminar",
47
+ "button_edit": "Editar",
48
+ "button_list": "Lista",
49
+ "button_reload": "Recargar",
50
+ "button_save": "Guardar",
51
+ "button_settings": "Configuración",
52
+ "button_show": "Ver",
53
+ "toolbar_search": "Buscar...",
54
+ "view_discussions": "Discusiones",
55
+ "view_files": "Archivos",
56
+ "view_quick_actions": "Acciones rapidas",
57
+ "view_status_active": "Activo",
58
+ "view_status_inactive": "Inactivo"
59
+ }
60
+ }
61
+ },
62
+ "fr": {
63
+ "lesli": {
64
+ "application": {
65
+ "navigation_logout": ":lesli.application.navigation_logout:",
66
+ "navigation_my_profile": ":lesli.application.navigation_my_profile:"
67
+ },
68
+ "dashboards": {
69
+ "column_default": ":lesli.dashboards.column_default:",
70
+ "column_name": ":lesli.dashboards.column_name:",
71
+ "title": ":lesli.dashboards.title:",
72
+ "view_add_component": ":lesli.dashboards.view_add_component:"
73
+ },
74
+ "shared": {
75
+ "button_add_new": ":lesli.shared.button_add_new:",
76
+ "button_delete": ":lesli.shared.button_delete:",
77
+ "button_edit": ":lesli.shared.button_edit:",
78
+ "button_list": ":lesli.shared.button_list:",
79
+ "button_reload": ":lesli.shared.button_reload:",
80
+ "button_save": ":lesli.shared.button_save:",
81
+ "button_settings": ":lesli.shared.button_settings:",
82
+ "button_show": ":lesli.shared.button_show:",
83
+ "toolbar_search": ":lesli.shared.toolbar_search:",
84
+ "view_discussions": ":lesli.shared.view_discussions:",
85
+ "view_files": ":lesli.shared.view_files:",
86
+ "view_quick_actions": ":lesli.shared.view_quick_actions:",
87
+ "view_status_active": ":lesli.shared.view_status_active:",
88
+ "view_status_inactive": ":lesli.shared.view_status_inactive:"
89
+ }
90
+ }
91
+ },
92
+ "it": {
93
+ "lesli": {
94
+ "application": {
95
+ "navigation_logout": ":lesli.application.navigation_logout:",
96
+ "navigation_my_profile": ":lesli.application.navigation_my_profile:"
97
+ },
98
+ "dashboards": {
99
+ "column_default": ":lesli.dashboards.column_default:",
100
+ "column_name": ":lesli.dashboards.column_name:",
101
+ "title": ":lesli.dashboards.title:",
102
+ "view_add_component": ":lesli.dashboards.view_add_component:"
103
+ },
104
+ "shared": {
105
+ "button_add_new": ":lesli.shared.button_add_new:",
106
+ "button_delete": ":lesli.shared.button_delete:",
107
+ "button_edit": ":lesli.shared.button_edit:",
108
+ "button_list": ":lesli.shared.button_list:",
109
+ "button_reload": ":lesli.shared.button_reload:",
110
+ "button_save": ":lesli.shared.button_save:",
111
+ "button_settings": ":lesli.shared.button_settings:",
112
+ "button_show": ":lesli.shared.button_show:",
113
+ "toolbar_search": ":lesli.shared.toolbar_search:",
114
+ "view_discussions": ":lesli.shared.view_discussions:",
115
+ "view_files": ":lesli.shared.view_files:",
116
+ "view_quick_actions": ":lesli.shared.view_quick_actions:",
117
+ "view_status_active": ":lesli.shared.view_status_active:",
118
+ "view_status_inactive": ":lesli.shared.view_status_inactive:"
119
+ }
120
+ }
121
+ },
122
+ "pt": {
123
+ "lesli": {
124
+ "application": {
125
+ "navigation_logout": ":lesli.application.navigation_logout:",
126
+ "navigation_my_profile": ":lesli.application.navigation_my_profile:"
127
+ },
128
+ "dashboards": {
129
+ "column_default": ":lesli.dashboards.column_default:",
130
+ "column_name": ":lesli.dashboards.column_name:",
131
+ "title": ":lesli.dashboards.title:",
132
+ "view_add_component": ":lesli.dashboards.view_add_component:"
133
+ },
134
+ "shared": {
135
+ "button_add_new": ":lesli.shared.button_add_new:",
136
+ "button_delete": ":lesli.shared.button_delete:",
137
+ "button_edit": ":lesli.shared.button_edit:",
138
+ "button_list": ":lesli.shared.button_list:",
139
+ "button_reload": ":lesli.shared.button_reload:",
140
+ "button_save": ":lesli.shared.button_save:",
141
+ "button_settings": ":lesli.shared.button_settings:",
142
+ "button_show": ":lesli.shared.button_show:",
143
+ "toolbar_search": ":lesli.shared.toolbar_search:",
144
+ "view_discussions": ":lesli.shared.view_discussions:",
145
+ "view_files": ":lesli.shared.view_files:",
146
+ "view_quick_actions": ":lesli.shared.view_quick_actions:",
147
+ "view_status_active": ":lesli.shared.view_status_active:",
148
+ "view_status_inactive": ":lesli.shared.view_status_inactive:"
149
+ }
150
+ }
151
+ }
152
+ }