lesli 5.0.22 → 5.0.24

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.
Files changed (166) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +1 -2
  3. data/app/assets/config/lesli_manifest.js +2 -2
  4. data/app/assets/images/lesli/brand/register-background.jpg +0 -0
  5. data/app/assets/stylesheets/lesli/application.css +1 -0
  6. data/app/controllers/lesli/abouts_controller.rb +12 -13
  7. data/app/controllers/lesli/application_controller.rb +1 -42
  8. data/app/controllers/lesli/application_lesli_controller.rb +8 -1
  9. data/app/controllers/lesli/apps_controller.rb +25 -0
  10. data/app/{models/lesli/user/journal.rb → controllers/lesli/item/activities_controller.rb} +3 -3
  11. data/app/controllers/lesli/item/discussions_controller.rb +126 -0
  12. data/app/controllers/lesli/item/tasks_controller.rb +126 -0
  13. data/app/controllers/lesli/{system_controllers_controller.rb → resources_controller.rb} +3 -3
  14. data/app/controllers/lesli/shared/dashboards_controller.rb +11 -279
  15. data/app/helpers/lesli/customization_helper.rb +3 -3
  16. data/app/helpers/lesli/html_helper.rb +114 -2
  17. data/app/helpers/lesli/navigation_helper.rb +8 -25
  18. data/app/helpers/lesli/system_helper.rb +21 -4
  19. data/app/helpers/lesli/turbo_helper.rb +19 -2
  20. data/app/interfaces/lesli/requester_interface.rb +2 -29
  21. data/app/interfaces/lesli/responder_interface.rb +121 -61
  22. data/app/models/concerns/lesli/account_initializer.rb +13 -13
  23. data/{lib/rspec/factories/lesli_account.rb → app/models/concerns/lesli/account_logs.rb} +23 -9
  24. data/app/models/concerns/lesli/item/activities.rb +106 -0
  25. data/app/models/concerns/lesli/item/discussions.rb +92 -0
  26. data/app/models/concerns/lesli/item/tasks.rb +95 -0
  27. data/app/models/concerns/lesli/user_extensions.rb +33 -51
  28. data/app/models/lesli/account.rb +7 -5
  29. data/app/models/lesli/application_lesli_record.rb +14 -0
  30. data/app/models/lesli/item/activity.rb +5 -1
  31. data/app/models/lesli/item/discussion.rb +10 -0
  32. data/{db/migrate/v1/0000110310_create_lesli_account_settings.rb → app/models/lesli/item/task.rb} +9 -4
  33. data/{db/migrate/v1/0000100110_create_lesli_system_controllers.rb → app/models/lesli/resource.rb} +10 -11
  34. data/app/models/lesli/role.rb +2 -17
  35. data/app/models/lesli/shared/dashboard.rb +1 -0
  36. data/app/models/lesli/user.rb +23 -77
  37. data/app/services/lesli/application_lesli_service.rb +21 -4
  38. data/app/{operators/lesli/controller_operator.rb → services/lesli/resource_service.rb} +92 -23
  39. data/app/services/lesli/role_service.rb +15 -9
  40. data/app/services/lesli/user_service.rb +28 -27
  41. data/app/views/lesli/apps/show.html.erb +1 -1
  42. data/app/views/lesli/errors/not_found.html.erb +1 -1
  43. data/app/views/lesli/errors/unauthorized.html.erb +9 -11
  44. data/app/views/lesli/layouts/application-devise.html.erb +5 -5
  45. data/app/views/lesli/layouts/application-lesli.html.erb +8 -7
  46. data/app/views/lesli/layouts/application-public.html.erb +4 -4
  47. data/app/views/lesli/layouts/mailer.html.erb +1 -1
  48. data/app/views/lesli/partials/{_application-analytics.html.erb → _application-lesli-analytics.html.erb} +14 -3
  49. data/app/views/lesli/partials/{_application-lesli-css.html.erb → _application-lesli-assets.html.erb} +8 -4
  50. data/app/views/lesli/partials/{_application-head.html.erb → _application-lesli-head.html.erb} +2 -2
  51. data/app/views/lesli/partials/_application-lesli-header.html.erb +18 -6
  52. data/app/views/lesli/partials/_application-lesli-navigation.html.erb +3 -6
  53. data/app/views/lesli/partials/_application-lesli-notifications.html.erb +0 -1
  54. data/app/views/lesli/partials/turbo/_redirection.html.erb +5 -0
  55. data/app/views/lesli/shared/dashboards/{_edit.html.erb → edit.html.erb} +3 -3
  56. data/app/views/lesli/shared/dashboards/{_show.html.erb → show.html.erb} +3 -3
  57. data/config/brakeman.yml +55 -0
  58. data/config/importmap.rb +0 -3
  59. data/config/initializers/devise.rb +1 -2
  60. data/config/initializers/lesli.rb +27 -14
  61. data/config/initializers/lesli_migration_helpers.rb +2 -7
  62. data/config/locales/translations.en.yml +6 -2
  63. data/config/locales/translations.es.yml +5 -2
  64. data/config/locales/translations.fr.yml +1 -4
  65. data/config/locales/translations.it.yml +5 -2
  66. data/config/locales/translations.pt.yml +1 -4
  67. data/config/routes.rb +4 -6
  68. data/db/migrate/v1/{0000000310_create_lesli_users.rb → 0000000210_create_lesli_users.rb} +4 -0
  69. data/db/migrate/v1/{0000000210_create_lesli_roles.rb → 0000000310_create_lesli_roles.rb} +6 -0
  70. data/db/migrate/v1/{0000130210_create_lesli_user_roles.rb → 0000000410_create_lesli_resources.rb} +8 -4
  71. data/db/seed/users.rb +1 -1
  72. data/db/seed/xyz.rb +3 -1
  73. data/lib/generators/lesli/install/install_generator.rb +1 -1
  74. data/lib/generators/lesli/spec/spec_generator.rb +0 -3
  75. data/lib/generators/lesli/view/view_generator.rb +0 -3
  76. data/lib/lesli/configuration.rb +1 -1
  77. data/{app/lib → lib}/lesli/courier.rb +40 -7
  78. data/lib/lesli/engine.rb +2 -2
  79. data/lib/lesli/router.rb +87 -0
  80. data/lib/lesli/version.rb +2 -2
  81. data/lib/lesli.rb +3 -2
  82. data/lib/migrate/common.rb +3 -1
  83. data/lib/migrate/items/activity_structure.rb +23 -7
  84. data/lib/migrate/items/discussion_structure.rb +10 -4
  85. data/lib/migrate/items/{action_structure.rb → task_structure.rb} +14 -7
  86. data/lib/migrate/shared/catalog_structure.rb +16 -0
  87. data/lib/scss/_apps.scss +1 -0
  88. data/lib/tasks/lesli/db.rake +14 -5
  89. data/lib/tasks/lesli/{controllers.rake → resources.rake} +4 -4
  90. data/lib/tasks/lesli_tasks.rake +13 -1
  91. data/readme.md +61 -68
  92. metadata +41 -106
  93. data/app/helpers/lesli/assets_helper.rb +0 -74
  94. data/app/helpers/lesli/general_helper.rb +0 -96
  95. data/app/mailers/lesli/devise_mailer.rb +0 -67
  96. data/app/models/concerns/lesli/has_activities.rb +0 -29
  97. data/app/models/concerns/lesli/user_activities.rb +0 -165
  98. data/app/models/concerns/lesli/user_security.rb +0 -220
  99. data/app/models/lesli/account/detail.rb +0 -37
  100. data/app/models/lesli/account/log.rb +0 -57
  101. data/app/models/lesli/account/request.rb +0 -37
  102. data/app/models/lesli/descriptor/privilege.rb +0 -39
  103. data/app/models/lesli/descriptor.rb +0 -57
  104. data/app/models/lesli/role/action.rb +0 -73
  105. data/app/models/lesli/role/privilege.rb +0 -38
  106. data/app/models/lesli/system_controller/action.rb +0 -37
  107. data/app/models/lesli/system_controller.rb +0 -104
  108. data/app/models/lesli/user/activity.rb +0 -5
  109. data/app/models/lesli/user/detail.rb +0 -55
  110. data/app/models/lesli/user/request.rb +0 -38
  111. data/app/models/lesli/user/role.rb +0 -39
  112. data/app/models/lesli/user/session.rb +0 -79
  113. data/app/models/lesli/user/setting.rb +0 -46
  114. data/app/operators/lesli/role_operator.rb +0 -153
  115. data/app/services/lesli/role/action_service.rb +0 -75
  116. data/app/services/lesli/user/session_service.rb +0 -78
  117. data/app/validators/lesli/application_lesli_validator.rb +0 -67
  118. data/app/validators/lesli/users_validator.rb +0 -217
  119. data/app/views/lesli/emails/user_mailer/invitation.html.erb +0 -23
  120. data/app/views/lesli/partials/_application-lesli-annoouncements.html.erb +0 -49
  121. data/app/views/lesli/partials/_application-lesli-javascript.html.erb +0 -46
  122. data/app/views/lesli/wrappers/_application-devise-simple.erb +0 -59
  123. data/app/views/lesli/wrappers/_application-devise.html.erb +0 -76
  124. data/db/migrate/v1/0000100210_create_lesli_system_controller_actions.rb +0 -42
  125. data/db/migrate/v1/0000110210_create_lesli_account_details.rb +0 -70
  126. data/db/migrate/v1/0000110410_create_lesli_account_activities.rb +0 -37
  127. data/db/migrate/v1/0000120210_create_lesli_role_actions.rb +0 -45
  128. data/db/migrate/v1/0000120310_create_lesli_role_privileges.rb +0 -45
  129. data/db/migrate/v1/0000130310_create_lesli_user_sessions.rb +0 -56
  130. data/db/migrate/v1/0000130410_create_lesli_user_activities.rb +0 -37
  131. data/db/migrate2/0000100510_create_lesli_account_locations.rb +0 -64
  132. data/db/migrate2/0000100610_create_lesli_account_currencies.rb +0 -48
  133. data/db/structure/00000000_locations.json +0 -32
  134. data/db/structure/00000020_catalogs.json +0 -0
  135. data/db/structure/00000201_workflows.json +0 -17
  136. data/db/structure/00000202_workflow_statuses.json +0 -24
  137. data/db/structure/00000203_workflow_associations.json +0 -14
  138. data/db/structure/00000204_workflow_actions.json +0 -39
  139. data/db/structure/00000205_workflow_checks.json +0 -27
  140. data/db/structure/00000300_custom_fields.json +0 -8
  141. data/db/structure/00000301_custom_fields.json +0 -38
  142. data/db/structure/00000401_custom_validations.json +0 -14
  143. data/db/structure/00000402_custom_validation_rules.json +0 -23
  144. data/db/structure/00000403_custom_validation_fields.json +0 -14
  145. data/lib/assets/javascripts/lesli/i18n_js +0 -1095
  146. data/lib/lesli/routing.rb +0 -87
  147. data/lib/migrate/shared/dashboard_structure.rb +0 -54
  148. data/lib/migrate/shared/setting_structure.rb +0 -20
  149. data/lib/rspec/config/spec_coverage.rb +0 -95
  150. data/lib/rspec/factories/lesli_role.rb +0 -62
  151. data/lib/rspec/factories/lesli_user.rb +0 -64
  152. data/lib/rspec/fixtures/files/lesli-icon.png +0 -0
  153. data/lib/rspec/fixtures/files/test_file_1.docx +0 -0
  154. data/lib/rspec/helpers/lesli_helper.rb +0 -65
  155. data/lib/rspec/helpers/rails_helper.rb +0 -134
  156. data/lib/rspec/helpers/response_request_helper.rb +0 -214
  157. data/lib/rspec/helpers/response_service_helper.rb +0 -66
  158. data/lib/rspec/helpers/spec_helper.rb +0 -99
  159. data/lib/rspec/lesli_api_tester.rb +0 -133
  160. data/lib/rspec/lesli_service_tester.rb +0 -46
  161. data/lib/rspec/testers/controller.rb +0 -63
  162. data/lib/rspec/testers/model.rb +0 -36
  163. data/lib/rspec/testers/request.rb +0 -93
  164. data/lib/tasks/lesli/docs.rake +0 -47
  165. data/lib/tasks/lesli/git.rake +0 -70
  166. data/lib/tasks/lesli/github.rake +0 -89
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6745cdd0cef2e17bdfbcfbeaa98b764cc17a0e4a08973a1f0f9602437aa36f05
4
- data.tar.gz: ced2199cfd580ff4b713088317764bac7b3c9c4c6b27011f1567abcc11d96171
3
+ metadata.gz: a56fbd90769c845789e9fc2097da330344938d31db26be4da238adae6e18ded8
4
+ data.tar.gz: 840585ccd69d395bde16bbd9b41e4b33e4cd41343e09f35b12fe7f5452e6b513
5
5
  SHA512:
6
- metadata.gz: 7df7919455d0486fa70cd31dac4cb448bfe766b1b71707f243efca570a9197bd15f179e61d80bcc7f6f871426bf057e8575c0965d0d235109e69b4953e920a29
7
- data.tar.gz: d94812f844319558b726d5f701091260ffaa3ccee39a12330f293fc8907c4fe745107a4eebb36b51ad740f536663066141202ee6be9684d32cc2a93f08cfadcd
6
+ metadata.gz: 20d6570450c48ca8c79132403144d12c7a718dd6b91c03e346899badeacad0d2627543f0f5b5dd98274edbb600b6073c2147ac27ef09a694acd0a3d257466a19
7
+ data.tar.gz: 6ab41da8a99d0b615071dedce1a4f020be93d4ffe85de5ae48a6fd5538182cec1194ff38b2daa79a16d901441463f5e376e67c403baf4a1e09509e1a3539c09c
data/Rakefile CHANGED
@@ -1,8 +1,7 @@
1
1
  require "bundler/setup"
2
2
 
3
3
  APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
4
- load "rails/tasks/engine.rake"
5
4
 
6
- load "rails/tasks/statistics.rake"
5
+ load "rails/tasks/engine.rake"
7
6
 
8
7
  require "bundler/gem_tasks"
@@ -30,13 +30,13 @@ Building a better future, one line of code at a time.
30
30
  */
31
31
 
32
32
 
33
- // · Engine asssets
33
+ // · Engine images
34
34
  // · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
35
35
  //= link_tree ../images/lesli .png
36
36
  //= link_tree ../images/lesli .jpg
37
37
  //= link_tree ../images/lesli .svg
38
38
 
39
- // ·
39
+ // · Engine styles and scripts
40
40
  // · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
41
41
  //= link lesli/application.css
42
42
  //= link lesli/application.js
@@ -181,6 +181,7 @@ body.lesli.apps.show .engines a svg {
181
181
  }
182
182
  body.lesli.apps.show .engines a p {
183
183
  font-size: 14;
184
+ font-family: "OpenSans";
184
185
  }
185
186
  body.lesli.apps.show .engines a span {
186
187
  font-weight: 600;
@@ -2,7 +2,7 @@
2
2
 
3
3
  Lesli
4
4
 
5
- Copyright (c) 2023, Lesli Technologies, S. A.
5
+ Copyright (c) 2025, Lesli Technologies, S. A.
6
6
 
7
7
  This program is free software: you can redistribute it and/or modify
8
8
  it under the terms of the GNU General Public License as published by
@@ -19,7 +19,7 @@ along with this program. If not, see http://www.gnu.org/licenses/.
19
19
 
20
20
  Lesli · Ruby on Rails SaaS Development Framework.
21
21
 
22
- Made with ♥ by https://www.lesli.tech
22
+ Made with ♥ by LesliTech
23
23
  Building a better future, one line of code at a time.
24
24
 
25
25
  @contact hello@lesli.tech
@@ -37,21 +37,20 @@ module Lesli
37
37
  skip_before_action :authenticate_request, only: [:welcome] if defined?(LesliShield)
38
38
  skip_before_action :authorize_request, only: [:welcome] if defined?(LesliShield)
39
39
 
40
- # def status
41
- # respond_with_successful({ :Lesli => "Ruby on Rails SaaS Development Framework." })
42
- # end
43
-
44
40
  def welcome
41
+ # renders the welcome page
45
42
  end
46
43
 
44
+ def up
45
+ # renders the health check page
46
+ end
47
+
47
48
  # GET /status
48
49
  def show
49
50
  respond_to do |format|
50
51
  format.html {}
51
- format.json {
52
-
53
- # get installed engines
54
- @lesli_engines = LesliSystem.engines.map { |engine, engine_info|
52
+ format.json do
53
+ lesli_engines = ::LesliSystem.engines.map do |engine, engine_info|
55
54
  {
56
55
  :name => engine_info[:name],
57
56
  :code => engine_info[:code],
@@ -60,9 +59,9 @@ module Lesli
60
59
  :version => engine_info[:version],
61
60
  :description => engine_info[:description]
62
61
  }
63
- }
64
- respond_with_successful(@lesli_engines)
65
- }
62
+ end
63
+ respond_with_json(lesli_engines)
64
+ end
66
65
  end
67
66
  end
68
67
  end
@@ -34,7 +34,7 @@ module Lesli
34
34
  class ApplicationController < ActionController::Base
35
35
  layout "lesli/layouts/application-public"
36
36
 
37
- add_flash_types(:info, :danger, :success, :warning)
37
+ protect_from_forgery with: :exception
38
38
 
39
39
  attr_reader :query
40
40
  attr_reader :engine_path
@@ -46,47 +46,6 @@ module Lesli
46
46
  }
47
47
  end
48
48
 
49
- # Meta-programming to define flash setter methods dynamically
50
- # success("Everything worked!")
51
- # danger("Oops, there was an error.")
52
- # info("Just an informational message.")
53
- # warning("This is a warning.")
54
- [:success, :danger, :warning, :info].each do |flash_type|
55
- define_method(flash_type) do |message|
56
- flash[flash_type] = message
57
- end
58
- end
59
-
60
- def language
61
-
62
- # check if param locale was sent by the user
63
- unless params[:locale].blank?
64
-
65
- locale = params[:locale].to_sym
66
-
67
- # check if locale requested is valid
68
- if I18n.available_locales.include?(locale)
69
-
70
- # save requested locale in session
71
- # this will be used in application_controller#switch_locale
72
- session[:locale] = locale
73
-
74
- end
75
-
76
- end
77
-
78
- I18n.locale = locale
79
-
80
- redirect_back(fallback_location: request.referer)
81
-
82
- # This code is not really executed
83
- # respond_with_successful({
84
- # locale: I18n.locale,
85
- # default_locale: I18n.default_locale,
86
- # available_locales: I18n.available_locales
87
- # })
88
- end
89
-
90
49
  # # Set the user language based on url configuration or browser/os default language (ready for public pages)
91
50
  # def set_locale
92
51
  # # language defined in the http header request
@@ -42,7 +42,6 @@ module Lesli
42
42
 
43
43
  protect_from_forgery with: :exception
44
44
 
45
- before_action :set_path
46
45
  before_action :set_locale
47
46
  before_action :authenticate_request if defined?(LesliShield)
48
47
  before_action :authorize_request if defined?(LesliShield)
@@ -56,5 +55,13 @@ module Lesli
56
55
  rescue_from ActionController::ParameterMissing do |_e|
57
56
  respond_with_error("Missing params")
58
57
  end
58
+
59
+ def log(payload)
60
+ payload[:engine] = self.class.module_parent
61
+ payload[:source] = self.class.name
62
+ payload[:action] = action_name
63
+ payload[:session_id] = session[:user_session_id]
64
+ current_user.log(**payload)
65
+ end
59
66
  end
60
67
  end
@@ -1,6 +1,31 @@
1
1
  module Lesli
2
2
  class AppsController < ApplicationLesliController
3
+
3
4
  def show
5
+ # renders the engine selector view
6
+ end
7
+
8
+ def language
9
+
10
+ # check if param locale was sent by the user
11
+ unless params[:locale].blank?
12
+
13
+ locale = params[:locale].to_sym
14
+
15
+ # check if locale requested is valid
16
+ if I18n.available_locales.include?(locale)
17
+
18
+ # save requested locale in session
19
+ # this will be used in application_controller#switch_locale
20
+ session[:locale] = locale
21
+
22
+ end
23
+
24
+ end
25
+
26
+ I18n.locale = locale
27
+
28
+ redirect_back(fallback_location: request.referer)
4
29
  end
5
30
  end
6
31
  end
@@ -31,8 +31,8 @@ Building a better future, one line of code at a time.
31
31
  =end
32
32
 
33
33
  module Lesli
34
- class User::Journal < ApplicationRecord
35
- belongs_to :user
36
- belongs_to :user_session, optional: true
34
+ module Item
35
+ class ActivitiesController < ApplicationLesliController
36
+ end
37
37
  end
38
38
  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 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
@@ -2,7 +2,7 @@
2
2
 
3
3
  Lesli
4
4
 
5
- Copyright (c) 2023, Lesli Technologies, S. A.
5
+ Copyright (c) 2026, Lesli Technologies, S. A.
6
6
 
7
7
  This program is free software: you can redistribute it and/or modify
8
8
  it under the terms of the GNU General Public License as published by
@@ -19,7 +19,7 @@ along with this program. If not, see http://www.gnu.org/licenses/.
19
19
 
20
20
  Lesli · Ruby on Rails SaaS Development Framework.
21
21
 
22
- Made with ♥ by https://www.lesli.tech
22
+ Made with ♥ by LesliTech
23
23
  Building a better future, one line of code at a time.
24
24
 
25
25
  @contact hello@lesli.tech
@@ -31,7 +31,7 @@ Building a better future, one line of code at a time.
31
31
  =end
32
32
 
33
33
  module Lesli
34
- class SystemControllersController < ApplicationLesliController
34
+ class ResourcesController < ApplicationLesliController
35
35
  before_action :set_system_controller, only: [:show, :update, :destroy]
36
36
 
37
37
  # GET /system_controllers