lesli 5.0.23 → 5.1.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.
- checksums.yaml +4 -4
- data/app/assets/stylesheets/lesli/application.css +1 -192
- data/app/controllers/lesli/abouts_controller.rb +1 -1
- data/app/controllers/lesli/{items → item}/activities_controller.rb +1 -1
- data/app/controllers/lesli/item/discussions_controller.rb +126 -0
- data/app/controllers/lesli/item/tasks_controller.rb +126 -0
- data/app/helpers/lesli/customization_helper.rb +1 -1
- data/app/helpers/lesli/html_helper.rb +1 -1
- data/app/models/concerns/lesli/item/activities.rb +106 -0
- data/app/models/concerns/lesli/item/discussions.rb +92 -0
- data/app/models/concerns/lesli/item/tasks.rb +95 -0
- data/app/models/lesli/account.rb +1 -0
- data/app/models/lesli/{items → item}/activity.rb +5 -13
- data/app/models/lesli/item/discussion.rb +10 -0
- data/{lib/lesli/r_spec.rb → app/models/lesli/item/task.rb} +9 -10
- data/app/views/lesli/partials/_application-lesli-header.html.erb +12 -0
- data/config/initializers/lesli_migration_helpers.rb +2 -2
- data/db/migrate/v1/0000000210_create_lesli_users.rb +1 -1
- data/lib/generators/lesli/base_generator.rb +172 -0
- data/lib/generators/lesli/controller/controller_generator.rb +40 -0
- data/lib/generators/lesli/controller/templates/controller.rb.tt +86 -0
- data/lib/generators/lesli/install/install_generator.rb +1 -1
- data/lib/generators/lesli/model/model_generator.rb +44 -0
- data/lib/generators/lesli/model/templates/model.rb.tt +16 -0
- data/lib/generators/lesli/scaffold/scaffold_generator.rb +47 -0
- data/lib/generators/lesli/service/service_generator.rb +40 -0
- data/lib/generators/lesli/service/templates/service.rb.tt +44 -0
- data/lib/generators/lesli/views/templates/_form.html.erb.tt +22 -0
- data/lib/generators/lesli/views/templates/index.html.erb.tt +17 -0
- data/lib/generators/lesli/views/templates/new.html.erb.tt +4 -0
- data/lib/generators/lesli/views/templates/show.html.erb.tt +22 -0
- data/lib/generators/lesli/views/views_generator.rb +106 -0
- data/lib/lesli/engine.rb +1 -23
- data/lib/lesli/router.rb +42 -43
- data/lib/lesli/version.rb +2 -2
- data/lib/migrate/common.rb +1 -1
- data/lib/migrate/items/activity_structure.rb +11 -5
- data/lib/migrate/items/discussion_structure.rb +9 -3
- data/lib/migrate/items/{action_structure.rb → task_structure.rb} +12 -6
- data/lib/migrate/shared/catalog_structure.rb +16 -0
- data/lib/tasks/lesli/db.rake +9 -0
- data/readme.md +1 -1
- metadata +58 -79
- data/app/assets/config/lesli_manifest.js +0 -42
- data/app/assets/images/lesli/brand/app-auth.svg +0 -9
- data/app/assets/images/lesli/brand/app-icon.svg +0 -48
- data/app/assets/images/lesli/brand/app-logo.png +0 -0
- data/app/assets/images/lesli/brand/app-logo.svg +0 -4
- data/app/assets/images/lesli/brand/favicon.png +0 -0
- data/app/assets/images/lesli/brand/favicon.svg +0 -61
- data/app/assets/images/lesli/brand/login-background.jpg +0 -0
- data/app/assets/images/lesli/brand/register-background.jpg +0 -0
- data/app/assets/javascripts/lesli/application.js +0 -1
- data/app/controllers/lesli/items/actions_controller.rb +0 -122
- data/app/controllers/lesli/items/discussions_controller.rb +0 -93
- data/app/models/lesli/items/action.rb +0 -15
- data/app/models/lesli/items/discussion.rb +0 -15
- data/config/importmap.rb +0 -1
- data/db/structure/00000000_locations.json +0 -32
- data/db/structure/00000020_catalogs.json +0 -0
- data/db/structure/00000201_workflows.json +0 -17
- data/db/structure/00000202_workflow_statuses.json +0 -24
- data/db/structure/00000203_workflow_associations.json +0 -14
- data/db/structure/00000204_workflow_actions.json +0 -39
- data/db/structure/00000205_workflow_checks.json +0 -27
- data/db/structure/00000300_custom_fields.json +0 -8
- data/db/structure/00000301_custom_fields.json +0 -38
- data/db/structure/00000401_custom_validations.json +0 -14
- data/db/structure/00000402_custom_validation_rules.json +0 -23
- data/db/structure/00000403_custom_validation_fields.json +0 -14
- data/lib/generators/application_lesli_generator_base.rb +0 -164
- data/lib/generators/lesli/spec/USAGE +0 -8
- data/lib/generators/lesli/spec/spec_generator.rb +0 -22
- data/lib/generators/lesli/spec/templates/spec-factory.template +0 -17
- data/lib/generators/lesli/spec/templates/spec-model.template +0 -70
- data/lib/generators/lesli/view/USAGE +0 -8
- data/lib/generators/lesli/view/templates/spec-factory.template +0 -17
- data/lib/generators/lesli/view/templates/spec-model.template +0 -70
- data/lib/generators/lesli/view/view_generator.rb +0 -22
- data/lib/scss/_apps.scss +0 -94
- data/lib/scss/application.scss +0 -34
- data/lib/tasks/lesli/docs.rake +0 -47
- data/lib/tasks/lesli/git.rake +0 -70
- data/lib/tasks/lesli/github.rake +0 -89
- data/lib/test/config.rb +0 -111
- data/lib/test/helpers/response_integration_helper.rb +0 -46
- data/lib/test/lesli.rb +0 -61
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8e75a2365623cbc3a027ab7f7d3369b889e4338329abc2d2c0a6c1a02d13e85c
|
|
4
|
+
data.tar.gz: 16b78e83a7728bc919a99cba8ab98cbd3fecd3b399181c5c702eeba86e9a2331
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 63ad9a17d31d1d42da5559882dcd5148af37930159becd88023937ae25a08d53f213795e371d6a970412863c85e838c4c3a0f620e0d51836a3d13a93a5ab4fd5
|
|
7
|
+
data.tar.gz: ec30a9449b36d01f07777f793bcff6993ace743fd3f9b015d07dd1403c01d11eb439d4822aaf8625a34dc87c4b8cb8a5014bc6b3764b65e6a3ed76dd028eb2b9
|
|
@@ -1,192 +1 @@
|
|
|
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
|
-
Lesli
|
|
34
|
-
|
|
35
|
-
Copyright (c) 2025, Lesli Technologies, S. A.
|
|
36
|
-
|
|
37
|
-
This program is free software: you can redistribute it and/or modify
|
|
38
|
-
it under the terms of the GNU General Public License as published by
|
|
39
|
-
the Free Software Foundation, either version 3 of the License, or
|
|
40
|
-
(at your option) any later version.
|
|
41
|
-
|
|
42
|
-
This program is distributed in the hope that it will be useful,
|
|
43
|
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
44
|
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
45
|
-
GNU General Public License for more details.
|
|
46
|
-
|
|
47
|
-
You should have received a copy of the GNU General Public License
|
|
48
|
-
along with this program. If not, see http://www.gnu.org/licenses/.
|
|
49
|
-
|
|
50
|
-
Lesli · Ruby on Rails SaaS Development Framework.
|
|
51
|
-
|
|
52
|
-
Made with ♥ by LesliTech
|
|
53
|
-
Building a better future, one line of code at a time.
|
|
54
|
-
|
|
55
|
-
@contact hello@lesli.tech
|
|
56
|
-
@website https://www.lesli.tech
|
|
57
|
-
@license GPLv3 http://www.gnu.org/licenses/gpl-3.0.en.html
|
|
58
|
-
|
|
59
|
-
// · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
|
|
60
|
-
// ·
|
|
61
|
-
*/
|
|
62
|
-
/**
|
|
63
|
-
Lesli
|
|
64
|
-
|
|
65
|
-
Copyright (c) 2025, Lesli Technologies, S. A.
|
|
66
|
-
|
|
67
|
-
This program is free software: you can redistribute it and/or modify
|
|
68
|
-
it under the terms of the GNU General Public License as published by
|
|
69
|
-
the Free Software Foundation, either version 3 of the License, or
|
|
70
|
-
(at your option) any later version.
|
|
71
|
-
|
|
72
|
-
This program is distributed in the hope that it will be useful,
|
|
73
|
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
74
|
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
75
|
-
GNU General Public License for more details.
|
|
76
|
-
|
|
77
|
-
You should have received a copy of the GNU General Public License
|
|
78
|
-
along with this program. If not, see http://www.gnu.org/licenses/.
|
|
79
|
-
|
|
80
|
-
Lesli - SCSS Utilities for websites, apps and web applications
|
|
81
|
-
|
|
82
|
-
Made with ♥ by LesliTech
|
|
83
|
-
Building a better future, one line of code at a time.
|
|
84
|
-
|
|
85
|
-
@contact hello@lesli.tech
|
|
86
|
-
@website https://www.lesli.tech
|
|
87
|
-
@license GPLv3 http://www.gnu.org/licenses/gpl-3.0.en.html
|
|
88
|
-
|
|
89
|
-
// · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
|
|
90
|
-
// ·
|
|
91
|
-
*/
|
|
92
|
-
/*
|
|
93
|
-
Lesli
|
|
94
|
-
|
|
95
|
-
Copyright (c) 2025, Lesli Technologies, S. A.
|
|
96
|
-
|
|
97
|
-
This program is free software: you can redistribute it and/or modify
|
|
98
|
-
it under the terms of the GNU General Public License as published by
|
|
99
|
-
the Free Software Foundation, either version 3 of the License, or
|
|
100
|
-
(at your option) any later version.
|
|
101
|
-
|
|
102
|
-
This program is distributed in the hope that it will be useful,
|
|
103
|
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
104
|
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
105
|
-
GNU General Public License for more details.
|
|
106
|
-
|
|
107
|
-
You should have received a copy of the GNU General Public License
|
|
108
|
-
along with this program. If not, see http://www.gnu.org/licenses/.
|
|
109
|
-
|
|
110
|
-
Lesli - SCSS Utilities for websites, apps and web applications
|
|
111
|
-
|
|
112
|
-
Made with ♥ by LesliTech
|
|
113
|
-
Building a better future, one line of code at a time.
|
|
114
|
-
|
|
115
|
-
@contact hello@lesli.tech
|
|
116
|
-
@website https://www.lesli.tech
|
|
117
|
-
@license GPLv3 http://www.gnu.org/licenses/gpl-3.0.en.html
|
|
118
|
-
|
|
119
|
-
// · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
|
|
120
|
-
// ·
|
|
121
|
-
*/
|
|
122
|
-
/**
|
|
123
|
-
Lesli
|
|
124
|
-
|
|
125
|
-
Copyright (c) 2025, Lesli Technologies, S. A.
|
|
126
|
-
|
|
127
|
-
This program is free software: you can redistribute it and/or modify
|
|
128
|
-
it under the terms of the GNU General Public License as published by
|
|
129
|
-
the Free Software Foundation, either version 3 of the License, or
|
|
130
|
-
(at your option) any later version.
|
|
131
|
-
|
|
132
|
-
This program is distributed in the hope that it will be useful,
|
|
133
|
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
134
|
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
135
|
-
GNU General Public License for more details.
|
|
136
|
-
|
|
137
|
-
You should have received a copy of the GNU General Public License
|
|
138
|
-
along with this program. If not, see http://www.gnu.org/licenses/.
|
|
139
|
-
|
|
140
|
-
Lesli - SCSS Utilities for websites, apps and web applications
|
|
141
|
-
|
|
142
|
-
Made with ♥ by LesliTech
|
|
143
|
-
Building a better future, one line of code at a time.
|
|
144
|
-
|
|
145
|
-
@contact hello@lesli.tech
|
|
146
|
-
@website https://www.lesli.tech
|
|
147
|
-
@license GPLv3 http://www.gnu.org/licenses/gpl-3.0.en.html
|
|
148
|
-
|
|
149
|
-
// · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
|
|
150
|
-
// ·
|
|
151
|
-
*/
|
|
152
|
-
body.lesli.apps.show .lesli-element-header {
|
|
153
|
-
margin-bottom: 5rem !important;
|
|
154
|
-
}
|
|
155
|
-
body.lesli.apps.show .engines {
|
|
156
|
-
gap: 24px;
|
|
157
|
-
margin-inline-end: auto;
|
|
158
|
-
margin-inline-start: auto;
|
|
159
|
-
}
|
|
160
|
-
body.lesli.apps.show .engines a {
|
|
161
|
-
flex-basis: 318px;
|
|
162
|
-
text-align: center;
|
|
163
|
-
padding: 2rem 0.4rem 2.8rem;
|
|
164
|
-
border: white 1px solid;
|
|
165
|
-
border-radius: 6px;
|
|
166
|
-
background-color: white;
|
|
167
|
-
transition: all ease-in-out 0.2s;
|
|
168
|
-
box-shadow: rgba(9, 30, 66, 0.25) 0px 4px 8px -2px, rgba(9, 30, 66, 0.08) 0px 0px 0px 1px;
|
|
169
|
-
}
|
|
170
|
-
body.lesli.apps.show .engines a:hover {
|
|
171
|
-
border-color: var(--lesli-color-primary);
|
|
172
|
-
transform: translateY(-2px);
|
|
173
|
-
}
|
|
174
|
-
body.lesli.apps.show .engines a.is-active {
|
|
175
|
-
background-color: #F0F4FF;
|
|
176
|
-
border-color: var(--lesli-color-primary);
|
|
177
|
-
}
|
|
178
|
-
body.lesli.apps.show .engines a svg {
|
|
179
|
-
margin-right: 0.4rem;
|
|
180
|
-
fill: var(--lesli-color-primary);
|
|
181
|
-
}
|
|
182
|
-
body.lesli.apps.show .engines a p {
|
|
183
|
-
font-size: 14;
|
|
184
|
-
font-family: "OpenSans";
|
|
185
|
-
}
|
|
186
|
-
body.lesli.apps.show .engines a span {
|
|
187
|
-
font-weight: 600;
|
|
188
|
-
font-size: 20px;
|
|
189
|
-
}
|
|
190
|
-
body.lesli.apps.show .engines a span, body.lesli.apps.show .engines a p {
|
|
191
|
-
color: var(--lesli-color-primary);
|
|
192
|
-
}
|
|
1
|
+
body.lesli.apps.show .lesli-element-header{margin-bottom:5rem !important}body.lesli.apps.show .engines{gap:24px;margin-inline-end:auto;margin-inline-start:auto}body.lesli.apps.show .engines a{flex-basis:318px;text-align:center;padding:2rem .4rem 2.8rem;border:#fff 1px solid;border-radius:6px;background-color:#fff;transition:all ease-in-out .2s;box-shadow:rgba(9,30,66,.25) 0px 4px 8px -2px,rgba(9,30,66,.08) 0px 0px 0px 1px}body.lesli.apps.show .engines a:hover{border-color:var(--lesli-color-primary);transform:translateY(-2px)}body.lesli.apps.show .engines a.is-active{background-color:#f0f4ff;border-color:var(--lesli-color-primary)}body.lesli.apps.show .engines a svg{margin-right:.4rem;fill:var(--lesli-color-primary)}body.lesli.apps.show .engines a p{font-size:14;font-family:"OpenSans"}body.lesli.apps.show .engines a span{font-weight:600;font-size:20px}body.lesli.apps.show .engines a span,body.lesli.apps.show .engines a p{color:var(--lesli-color-primary)}
|
|
@@ -50,7 +50,7 @@ module Lesli
|
|
|
50
50
|
respond_to do |format|
|
|
51
51
|
format.html {}
|
|
52
52
|
format.json do
|
|
53
|
-
lesli_engines = LesliSystem.engines.map do |engine, engine_info|
|
|
53
|
+
lesli_engines = ::LesliSystem.engines.map do |engine, engine_info|
|
|
54
54
|
{
|
|
55
55
|
:name => engine_info[:name],
|
|
56
56
|
:code => engine_info[:code],
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
=begin
|
|
2
|
+
|
|
3
|
+
Lesli
|
|
4
|
+
|
|
5
|
+
Copyright (c) 2026, 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
|
+
=end
|
|
32
|
+
|
|
33
|
+
module Lesli
|
|
34
|
+
module Item
|
|
35
|
+
class DiscussionsController < ApplicationLesliController
|
|
36
|
+
before_action :set_discussion, only: %i[show update]
|
|
37
|
+
before_action :set_discussable, only: %i[index create]
|
|
38
|
+
|
|
39
|
+
def index
|
|
40
|
+
@discussions = discussion_class
|
|
41
|
+
.where(account: current_user.account)
|
|
42
|
+
.order(created_at: :desc)
|
|
43
|
+
respond_with_lesli(json: @discussions)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def show
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def create
|
|
50
|
+
discussion = discussion_class.new(discussion_params)
|
|
51
|
+
|
|
52
|
+
discussion.user = current_user
|
|
53
|
+
discussion.account = current_user.account
|
|
54
|
+
discussion.discussable = @discussable if @discussable
|
|
55
|
+
|
|
56
|
+
if discussion.save
|
|
57
|
+
respond_with_lesli(:turbo => [
|
|
58
|
+
stream_notification_success("Discussion created"),
|
|
59
|
+
turbo_stream.prepend("#{scope_key}-lesli-items-discussions-list") do
|
|
60
|
+
LesliView::Item::Discussion.new(discussion).render_in(view_context)
|
|
61
|
+
end
|
|
62
|
+
])
|
|
63
|
+
else
|
|
64
|
+
respond_with_lesli(
|
|
65
|
+
:turbo => stream_notification_danger(discussion.errors.full_messages)
|
|
66
|
+
)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def update
|
|
71
|
+
@discussion.done = true
|
|
72
|
+
@discussion.save
|
|
73
|
+
respond_with_lesli(:turbo => [
|
|
74
|
+
stream_notification_success("Discussion updated #{@discussable}"),
|
|
75
|
+
turbo_stream.replace(helpers.dom_id(@discussion, scope_key)) do
|
|
76
|
+
LesliView::Item::Discussion.new(@discussion, scope_key).render_in(view_context)
|
|
77
|
+
end
|
|
78
|
+
])
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
private
|
|
82
|
+
|
|
83
|
+
# return a key to identify the engine where the tasks are running
|
|
84
|
+
def scope_key = ActiveSupport::Inflector.underscore(discussion_class.name).tr("/", "_")
|
|
85
|
+
|
|
86
|
+
# return the discussion class including the engine where the tasks are running
|
|
87
|
+
def discussion_class = self.class.module_parent.const_get("Discussion")
|
|
88
|
+
|
|
89
|
+
# validate we invoke only models that implements Lesli::Item::Discussions concern
|
|
90
|
+
def validate_discussable discussable
|
|
91
|
+
|
|
92
|
+
# 1. Attempt to resolve the class safely
|
|
93
|
+
klass = discussable.safe_constantize
|
|
94
|
+
|
|
95
|
+
# 2. VALIDATION: Check if the class is allowed to be discussable
|
|
96
|
+
# We check if the class exists AND if it includes your specific discussable trait
|
|
97
|
+
unless klass && klass.respond_to?(:is_lesli_taskable?) && klass.is_lesli_commentable?
|
|
98
|
+
render json: { error: "Unauthorized discussable type" }, status: :forbidden and return
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
klass
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def set_discussion
|
|
105
|
+
@discussion = discussion_class.where(account: current_user.account).find(params[:id])
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# Permite filtrar/crear para un actionable específico:
|
|
109
|
+
# params: actionable_type=LesliSupport::Ticket&actionable_id=123
|
|
110
|
+
def set_discussable
|
|
111
|
+
type = params[:discussable_type].presence
|
|
112
|
+
id = params[:discussable_id].presence
|
|
113
|
+
return if type.blank? || id.blank?
|
|
114
|
+
|
|
115
|
+
discussable = validate_discussable(type)
|
|
116
|
+
|
|
117
|
+
# 3. Execution: Now it is safe to query
|
|
118
|
+
@discussable = discussable.where(account: current_user.account).find_by(id: id)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def discussion_params
|
|
122
|
+
params.require(scope_key.to_sym).permit(:message)
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
=begin
|
|
2
|
+
|
|
3
|
+
Lesli
|
|
4
|
+
|
|
5
|
+
Copyright (c) 2026, 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
|
+
=end
|
|
32
|
+
|
|
33
|
+
module Lesli
|
|
34
|
+
module Item
|
|
35
|
+
class TasksController < ApplicationLesliController
|
|
36
|
+
before_action :set_task, only: %i[show update]
|
|
37
|
+
before_action :set_taskable, only: %i[index create]
|
|
38
|
+
|
|
39
|
+
def index
|
|
40
|
+
@tasks = task_class
|
|
41
|
+
.where(account: current_user.account)
|
|
42
|
+
.order(created_at: :desc)
|
|
43
|
+
respond_with_lesli(json: @tasks)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def show
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def create
|
|
50
|
+
task = task_class.new(task_params)
|
|
51
|
+
|
|
52
|
+
task.user = current_user
|
|
53
|
+
task.account = current_user.account
|
|
54
|
+
task.taskable = @taskable if @taskable
|
|
55
|
+
|
|
56
|
+
if task.save
|
|
57
|
+
respond_with_lesli(:turbo => [
|
|
58
|
+
stream_notification_success("Task created"),
|
|
59
|
+
turbo_stream.prepend("#{scope_key}-lesli-items-tasks-list") do
|
|
60
|
+
LesliView::Item::Task.new(task, scope_key).render_in(view_context)
|
|
61
|
+
end
|
|
62
|
+
])
|
|
63
|
+
else
|
|
64
|
+
respond_with_lesli(
|
|
65
|
+
:turbo => stream_notification_danger(task.errors.full_messages)
|
|
66
|
+
)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def update
|
|
71
|
+
@task.done = true
|
|
72
|
+
@task.save
|
|
73
|
+
respond_with_lesli(:turbo => [
|
|
74
|
+
stream_notification_success("Task updated #{@taskable}"),
|
|
75
|
+
turbo_stream.replace(helpers.dom_id(@task, scope_key)) do
|
|
76
|
+
LesliView::Item::Task.new(@task, scope_key).render_in(view_context)
|
|
77
|
+
end
|
|
78
|
+
])
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
private
|
|
82
|
+
|
|
83
|
+
# return a key to identify the engine where the tasks are running
|
|
84
|
+
def scope_key = ActiveSupport::Inflector.underscore(task_class.name).tr("/", "_")
|
|
85
|
+
|
|
86
|
+
# return the task class including the engine where the tasks are running
|
|
87
|
+
def task_class = self.class.module_parent.const_get("Task")
|
|
88
|
+
|
|
89
|
+
# validate we invoke only models that implements Lesli::Item::Tasks concern
|
|
90
|
+
def validate_taskable taskable
|
|
91
|
+
|
|
92
|
+
# 1. Attempt to resolve the class safely
|
|
93
|
+
klass = taskable.safe_constantize
|
|
94
|
+
|
|
95
|
+
# 2. VALIDATION: Check if the class is allowed to be taskable
|
|
96
|
+
# We check if the class exists AND if it includes your specific taskable trait
|
|
97
|
+
unless klass && klass.respond_to?(:is_lesli_taskable?) && klass.is_lesli_taskable?
|
|
98
|
+
render json: { error: "Unauthorized taskable type" }, status: :forbidden and return
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
klass
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def set_task
|
|
105
|
+
@task = task_class.where(account: current_user.account).find(params[:id])
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# Permite filtrar/crear para un actionable específico:
|
|
109
|
+
# params: actionable_type=LesliSupport::Ticket&actionable_id=123
|
|
110
|
+
def set_taskable
|
|
111
|
+
type = params[:taskable_type].presence
|
|
112
|
+
id = params[:taskable_id].presence
|
|
113
|
+
return if type.blank? || id.blank?
|
|
114
|
+
|
|
115
|
+
taskable = validate_taskable(type)
|
|
116
|
+
|
|
117
|
+
# 3. Execution: Now it is safe to query
|
|
118
|
+
@taskable = taskable.where(account: current_user.account).find_by(id: id)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def task_params
|
|
122
|
+
params.require(scope_key.to_sym).permit(:title)
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
@@ -45,7 +45,7 @@ module Lesli
|
|
|
45
45
|
def customization_instance_logo(tag: false, logo: "app-logo", variant: "light", mode: "web",
|
|
46
46
|
options: { alt: "Logo" })
|
|
47
47
|
# loading logo from builder assets
|
|
48
|
-
logo_path = "
|
|
48
|
+
logo_path = "lesli_assets/brand/#{logo}.svg"
|
|
49
49
|
|
|
50
50
|
# load favicon as PNG for better compatibility between web browsers
|
|
51
51
|
#logo_path = "#{lesli_instance_code}/brand/#{logo}.png" if logo == "favicon"
|
|
@@ -35,7 +35,7 @@ module Lesli
|
|
|
35
35
|
|
|
36
36
|
# Prints link tags to add favicon to websites
|
|
37
37
|
def lesli_favicon
|
|
38
|
-
icon_path = image_url("
|
|
38
|
+
icon_path = image_url("lesli_assets/brand/favicon.svg")
|
|
39
39
|
safe_join([
|
|
40
40
|
tag.link(href: icon_path, rel: "alternate icon"),
|
|
41
41
|
tag.link(href: icon_path, rel: "icon", type: "image/svg+xml"),
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
=begin
|
|
2
|
+
|
|
3
|
+
Lesli
|
|
4
|
+
|
|
5
|
+
Copyright (c) 2026, 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
|
+
=end
|
|
32
|
+
|
|
33
|
+
module Lesli
|
|
34
|
+
module Item
|
|
35
|
+
module Activities
|
|
36
|
+
extend ActiveSupport::Concern
|
|
37
|
+
|
|
38
|
+
included do
|
|
39
|
+
class_attribute :lesli_activities_class, instance_accessor: false
|
|
40
|
+
lesli_activities_setup
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
class_methods do
|
|
44
|
+
|
|
45
|
+
# Automatically sets the associations to the
|
|
46
|
+
# engine model that is implementing the task items
|
|
47
|
+
def lesli_activities_setup(use: nil, as: :subject, association_name: :activities)
|
|
48
|
+
klass = if use
|
|
49
|
+
use.to_s.constantize
|
|
50
|
+
else
|
|
51
|
+
"#{name.deconstantize}::Item::Activity".constantize
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
self.lesli_activities_class = klass
|
|
55
|
+
|
|
56
|
+
# ✅ Auto-fix table name (works even when engine defines table_name_prefix)
|
|
57
|
+
expected_table = lesli_expected_activity_table_name_for(klass)
|
|
58
|
+
|
|
59
|
+
if klass.table_name != expected_table
|
|
60
|
+
klass.table_name = expected_table
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Set associations
|
|
64
|
+
# Example:
|
|
65
|
+
# class LesliSupport::Ticket
|
|
66
|
+
# has_many :activities, class_name: "LesliSupport::Items::Activity"
|
|
67
|
+
# end
|
|
68
|
+
has_many(association_name,
|
|
69
|
+
-> { where(deleted_at: nil).order(created_at: :desc) },
|
|
70
|
+
as: as,
|
|
71
|
+
class_name: klass.name,
|
|
72
|
+
dependent: :destroy
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
# rescue NameError
|
|
76
|
+
# raise NameError,
|
|
77
|
+
# "Task class not found for #{name}. Expected #{name.deconstantize}::Activity or pass `use:`"
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
private
|
|
81
|
+
|
|
82
|
+
# Build: "lesli_support_item_activities" from "LesliSupport::Item::Activity"
|
|
83
|
+
#
|
|
84
|
+
# We DO NOT rely on ActiveRecord's table_name_prefix, because that’s what breaks your case.
|
|
85
|
+
def lesli_expected_activity_table_name_for(klass)
|
|
86
|
+
parts = klass.name.split("::").map(&:underscore) # ["lesli_support", "item", "activity"]
|
|
87
|
+
"#{parts.join('_').pluralize}" # "lesli_support_item_activities"
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def after_save_activities
|
|
92
|
+
L2.warn "You need to define your activity methods in your model"
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def activities_create **resource
|
|
96
|
+
self.activities.create(
|
|
97
|
+
subject_type: self.class.name,
|
|
98
|
+
subject_id: self.id,
|
|
99
|
+
user_id:self.user_id,
|
|
100
|
+
account_id:self.account_id,
|
|
101
|
+
**resource
|
|
102
|
+
)
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|