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.
- checksums.yaml +4 -4
- data/Rakefile +1 -2
- data/app/assets/config/lesli_manifest.js +2 -2
- data/app/assets/images/lesli/brand/register-background.jpg +0 -0
- data/app/assets/stylesheets/lesli/application.css +1 -0
- data/app/controllers/lesli/abouts_controller.rb +12 -13
- data/app/controllers/lesli/application_controller.rb +1 -42
- data/app/controllers/lesli/application_lesli_controller.rb +8 -1
- data/app/controllers/lesli/apps_controller.rb +25 -0
- data/app/{models/lesli/user/journal.rb → controllers/lesli/item/activities_controller.rb} +3 -3
- data/app/controllers/lesli/item/discussions_controller.rb +126 -0
- data/app/controllers/lesli/item/tasks_controller.rb +126 -0
- data/app/controllers/lesli/{system_controllers_controller.rb → resources_controller.rb} +3 -3
- data/app/controllers/lesli/shared/dashboards_controller.rb +11 -279
- data/app/helpers/lesli/customization_helper.rb +3 -3
- data/app/helpers/lesli/html_helper.rb +114 -2
- data/app/helpers/lesli/navigation_helper.rb +8 -25
- data/app/helpers/lesli/system_helper.rb +21 -4
- data/app/helpers/lesli/turbo_helper.rb +19 -2
- data/app/interfaces/lesli/requester_interface.rb +2 -29
- data/app/interfaces/lesli/responder_interface.rb +121 -61
- data/app/models/concerns/lesli/account_initializer.rb +13 -13
- data/{lib/rspec/factories/lesli_account.rb → app/models/concerns/lesli/account_logs.rb} +23 -9
- 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/concerns/lesli/user_extensions.rb +33 -51
- data/app/models/lesli/account.rb +7 -5
- data/app/models/lesli/application_lesli_record.rb +14 -0
- data/app/models/lesli/item/activity.rb +5 -1
- data/app/models/lesli/item/discussion.rb +10 -0
- data/{db/migrate/v1/0000110310_create_lesli_account_settings.rb → app/models/lesli/item/task.rb} +9 -4
- data/{db/migrate/v1/0000100110_create_lesli_system_controllers.rb → app/models/lesli/resource.rb} +10 -11
- data/app/models/lesli/role.rb +2 -17
- data/app/models/lesli/shared/dashboard.rb +1 -0
- data/app/models/lesli/user.rb +23 -77
- data/app/services/lesli/application_lesli_service.rb +21 -4
- data/app/{operators/lesli/controller_operator.rb → services/lesli/resource_service.rb} +92 -23
- data/app/services/lesli/role_service.rb +15 -9
- data/app/services/lesli/user_service.rb +28 -27
- data/app/views/lesli/apps/show.html.erb +1 -1
- data/app/views/lesli/errors/not_found.html.erb +1 -1
- data/app/views/lesli/errors/unauthorized.html.erb +9 -11
- data/app/views/lesli/layouts/application-devise.html.erb +5 -5
- data/app/views/lesli/layouts/application-lesli.html.erb +8 -7
- data/app/views/lesli/layouts/application-public.html.erb +4 -4
- data/app/views/lesli/layouts/mailer.html.erb +1 -1
- data/app/views/lesli/partials/{_application-analytics.html.erb → _application-lesli-analytics.html.erb} +14 -3
- data/app/views/lesli/partials/{_application-lesli-css.html.erb → _application-lesli-assets.html.erb} +8 -4
- data/app/views/lesli/partials/{_application-head.html.erb → _application-lesli-head.html.erb} +2 -2
- data/app/views/lesli/partials/_application-lesli-header.html.erb +18 -6
- data/app/views/lesli/partials/_application-lesli-navigation.html.erb +3 -6
- data/app/views/lesli/partials/_application-lesli-notifications.html.erb +0 -1
- data/app/views/lesli/partials/turbo/_redirection.html.erb +5 -0
- data/app/views/lesli/shared/dashboards/{_edit.html.erb → edit.html.erb} +3 -3
- data/app/views/lesli/shared/dashboards/{_show.html.erb → show.html.erb} +3 -3
- data/config/brakeman.yml +55 -0
- data/config/importmap.rb +0 -3
- data/config/initializers/devise.rb +1 -2
- data/config/initializers/lesli.rb +27 -14
- data/config/initializers/lesli_migration_helpers.rb +2 -7
- data/config/locales/translations.en.yml +6 -2
- data/config/locales/translations.es.yml +5 -2
- data/config/locales/translations.fr.yml +1 -4
- data/config/locales/translations.it.yml +5 -2
- data/config/locales/translations.pt.yml +1 -4
- data/config/routes.rb +4 -6
- data/db/migrate/v1/{0000000310_create_lesli_users.rb → 0000000210_create_lesli_users.rb} +4 -0
- data/db/migrate/v1/{0000000210_create_lesli_roles.rb → 0000000310_create_lesli_roles.rb} +6 -0
- data/db/migrate/v1/{0000130210_create_lesli_user_roles.rb → 0000000410_create_lesli_resources.rb} +8 -4
- data/db/seed/users.rb +1 -1
- data/db/seed/xyz.rb +3 -1
- data/lib/generators/lesli/install/install_generator.rb +1 -1
- data/lib/generators/lesli/spec/spec_generator.rb +0 -3
- data/lib/generators/lesli/view/view_generator.rb +0 -3
- data/lib/lesli/configuration.rb +1 -1
- data/{app/lib → lib}/lesli/courier.rb +40 -7
- data/lib/lesli/engine.rb +2 -2
- data/lib/lesli/router.rb +87 -0
- data/lib/lesli/version.rb +2 -2
- data/lib/lesli.rb +3 -2
- data/lib/migrate/common.rb +3 -1
- data/lib/migrate/items/activity_structure.rb +23 -7
- data/lib/migrate/items/discussion_structure.rb +10 -4
- data/lib/migrate/items/{action_structure.rb → task_structure.rb} +14 -7
- data/lib/migrate/shared/catalog_structure.rb +16 -0
- data/lib/scss/_apps.scss +1 -0
- data/lib/tasks/lesli/db.rake +14 -5
- data/lib/tasks/lesli/{controllers.rake → resources.rake} +4 -4
- data/lib/tasks/lesli_tasks.rake +13 -1
- data/readme.md +61 -68
- metadata +41 -106
- data/app/helpers/lesli/assets_helper.rb +0 -74
- data/app/helpers/lesli/general_helper.rb +0 -96
- data/app/mailers/lesli/devise_mailer.rb +0 -67
- data/app/models/concerns/lesli/has_activities.rb +0 -29
- data/app/models/concerns/lesli/user_activities.rb +0 -165
- data/app/models/concerns/lesli/user_security.rb +0 -220
- data/app/models/lesli/account/detail.rb +0 -37
- data/app/models/lesli/account/log.rb +0 -57
- data/app/models/lesli/account/request.rb +0 -37
- data/app/models/lesli/descriptor/privilege.rb +0 -39
- data/app/models/lesli/descriptor.rb +0 -57
- data/app/models/lesli/role/action.rb +0 -73
- data/app/models/lesli/role/privilege.rb +0 -38
- data/app/models/lesli/system_controller/action.rb +0 -37
- data/app/models/lesli/system_controller.rb +0 -104
- data/app/models/lesli/user/activity.rb +0 -5
- data/app/models/lesli/user/detail.rb +0 -55
- data/app/models/lesli/user/request.rb +0 -38
- data/app/models/lesli/user/role.rb +0 -39
- data/app/models/lesli/user/session.rb +0 -79
- data/app/models/lesli/user/setting.rb +0 -46
- data/app/operators/lesli/role_operator.rb +0 -153
- data/app/services/lesli/role/action_service.rb +0 -75
- data/app/services/lesli/user/session_service.rb +0 -78
- data/app/validators/lesli/application_lesli_validator.rb +0 -67
- data/app/validators/lesli/users_validator.rb +0 -217
- data/app/views/lesli/emails/user_mailer/invitation.html.erb +0 -23
- data/app/views/lesli/partials/_application-lesli-annoouncements.html.erb +0 -49
- data/app/views/lesli/partials/_application-lesli-javascript.html.erb +0 -46
- data/app/views/lesli/wrappers/_application-devise-simple.erb +0 -59
- data/app/views/lesli/wrappers/_application-devise.html.erb +0 -76
- data/db/migrate/v1/0000100210_create_lesli_system_controller_actions.rb +0 -42
- data/db/migrate/v1/0000110210_create_lesli_account_details.rb +0 -70
- data/db/migrate/v1/0000110410_create_lesli_account_activities.rb +0 -37
- data/db/migrate/v1/0000120210_create_lesli_role_actions.rb +0 -45
- data/db/migrate/v1/0000120310_create_lesli_role_privileges.rb +0 -45
- data/db/migrate/v1/0000130310_create_lesli_user_sessions.rb +0 -56
- data/db/migrate/v1/0000130410_create_lesli_user_activities.rb +0 -37
- data/db/migrate2/0000100510_create_lesli_account_locations.rb +0 -64
- data/db/migrate2/0000100610_create_lesli_account_currencies.rb +0 -48
- 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/assets/javascripts/lesli/i18n_js +0 -1095
- data/lib/lesli/routing.rb +0 -87
- data/lib/migrate/shared/dashboard_structure.rb +0 -54
- data/lib/migrate/shared/setting_structure.rb +0 -20
- data/lib/rspec/config/spec_coverage.rb +0 -95
- data/lib/rspec/factories/lesli_role.rb +0 -62
- data/lib/rspec/factories/lesli_user.rb +0 -64
- data/lib/rspec/fixtures/files/lesli-icon.png +0 -0
- data/lib/rspec/fixtures/files/test_file_1.docx +0 -0
- data/lib/rspec/helpers/lesli_helper.rb +0 -65
- data/lib/rspec/helpers/rails_helper.rb +0 -134
- data/lib/rspec/helpers/response_request_helper.rb +0 -214
- data/lib/rspec/helpers/response_service_helper.rb +0 -66
- data/lib/rspec/helpers/spec_helper.rb +0 -99
- data/lib/rspec/lesli_api_tester.rb +0 -133
- data/lib/rspec/lesli_service_tester.rb +0 -46
- data/lib/rspec/testers/controller.rb +0 -63
- data/lib/rspec/testers/model.rb +0 -36
- data/lib/rspec/testers/request.rb +0 -93
- data/lib/tasks/lesli/docs.rake +0 -47
- data/lib/tasks/lesli/git.rake +0 -70
- data/lib/tasks/lesli/github.rake +0 -89
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a56fbd90769c845789e9fc2097da330344938d31db26be4da238adae6e18ded8
|
|
4
|
+
data.tar.gz: 840585ccd69d395bde16bbd9b41e4b33e4cd41343e09f35b12fe7f5452e6b513
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 20d6570450c48ca8c79132403144d12c7a718dd6b91c03e346899badeacad0d2627543f0f5b5dd98274edbb600b6073c2147ac27ef09a694acd0a3d257466a19
|
|
7
|
+
data.tar.gz: 6ab41da8a99d0b615071dedce1a4f020be93d4ffe85de5ae48a6fd5538182cec1194ff38b2daa79a16d901441463f5e376e67c403baf4a1e09509e1a3539c09c
|
data/Rakefile
CHANGED
|
@@ -30,13 +30,13 @@ Building a better future, one line of code at a time.
|
|
|
30
30
|
*/
|
|
31
31
|
|
|
32
32
|
|
|
33
|
-
// · Engine
|
|
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
|
|
Binary file
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Lesli
|
|
4
4
|
|
|
5
|
-
Copyright (c)
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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)
|
|
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
|
|
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
|
|
34
|
+
class ResourcesController < ApplicationLesliController
|
|
35
35
|
before_action :set_system_controller, only: [:show, :update, :destroy]
|
|
36
36
|
|
|
37
37
|
# GET /system_controllers
|