lesli_babel 0.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.
Files changed (106) hide show
  1. checksums.yaml +7 -0
  2. data/Rakefile +5 -0
  3. data/app/assets/config/lesli_babel_manifest.js +7 -0
  4. data/app/assets/images/lesli_babel/babel-logo.svg +157 -0
  5. data/app/assets/javascripts/lesli_babel/application.js +3288 -0
  6. data/app/assets/stylesheets/lesli_babel/application.scss +41 -0
  7. data/app/assets/stylesheets/lesli_babel/dashboards.scss +55 -0
  8. data/app/assets/stylesheets/lesli_babel/modules.scss +33 -0
  9. data/app/assets/stylesheets/lesli_babel/translations.scss +58 -0
  10. data/app/controllers/lesli_babel/application_controller.rb +37 -0
  11. data/app/controllers/lesli_babel/buckets_controller.rb +79 -0
  12. data/app/controllers/lesli_babel/clones_controller.rb +80 -0
  13. data/app/controllers/lesli_babel/dashboards_controller.rb +38 -0
  14. data/app/controllers/lesli_babel/modules_controller.rb +91 -0
  15. data/app/controllers/lesli_babel/relevants_controller.rb +38 -0
  16. data/app/controllers/lesli_babel/strings_controller.rb +142 -0
  17. data/app/controllers/lesli_babel/translations_controller.rb +134 -0
  18. data/app/jobs/lesli_babel/application_job.rb +7 -0
  19. data/app/mailers/lesli_babel/application_mailer.rb +6 -0
  20. data/app/models/lesli_babel/application_record.rb +36 -0
  21. data/app/models/lesli_babel/bucket.rb +6 -0
  22. data/app/models/lesli_babel/clone.rb +24 -0
  23. data/app/models/lesli_babel/dashboard.rb +35 -0
  24. data/app/models/lesli_babel/module.rb +35 -0
  25. data/app/models/lesli_babel/relevant.rb +21 -0
  26. data/app/models/lesli_babel/string/activity.rb +5 -0
  27. data/app/models/lesli_babel/string/discussion.rb +68 -0
  28. data/app/models/lesli_babel/string.rb +225 -0
  29. data/app/models/lesli_babel/translation.rb +5 -0
  30. data/app/services/lesli_babel/module_service.rb +18 -0
  31. data/app/services/lesli_babel/old/translations_android_service.rb +82 -0
  32. data/app/services/lesli_babel/old/translations_clone_service.rb +161 -0
  33. data/app/services/lesli_babel/old/translations_flutter_service.rb +102 -0
  34. data/app/services/lesli_babel/old/translations_ios_service.rb +119 -0
  35. data/app/services/lesli_babel/old/translations_js_service.rb +114 -0
  36. data/app/services/lesli_babel/old/translations_middleman_service.rb +77 -0
  37. data/app/services/lesli_babel/old/translations_rails_service.rb +119 -0
  38. data/app/services/lesli_babel/old/translations_service.rb +97 -0
  39. data/app/services/lesli_babel/old/translations_synchronization_service.rb +215 -0
  40. data/app/services/lesli_babel/string_service.rb +80 -0
  41. data/app/views/lesli_babel/buckets/_form.html.erb +17 -0
  42. data/app/views/lesli_babel/buckets/edit.html.erb +6 -0
  43. data/app/views/lesli_babel/buckets/index.html.erb +25 -0
  44. data/app/views/lesli_babel/buckets/new.html.erb +5 -0
  45. data/app/views/lesli_babel/buckets/show.html.erb +4 -0
  46. data/app/views/lesli_babel/clones/_form.html.erb +19 -0
  47. data/app/views/lesli_babel/clones/edit.html.erb +20 -0
  48. data/app/views/lesli_babel/clones/index.html.erb +20 -0
  49. data/app/views/lesli_babel/clones/new.html.erb +20 -0
  50. data/app/views/lesli_babel/clones/show.html.erb +20 -0
  51. data/app/views/lesli_babel/dashboards/show.html.erb +1 -0
  52. data/app/views/lesli_babel/dashboards/stats..html.erb +1 -0
  53. data/app/views/lesli_babel/modules/_form.html.erb +17 -0
  54. data/app/views/lesli_babel/modules/edit.html.erb +1 -0
  55. data/app/views/lesli_babel/modules/index.html.erb +1 -0
  56. data/app/views/lesli_babel/modules/new.html.erb +1 -0
  57. data/app/views/lesli_babel/modules/show.html.erb +1 -0
  58. data/app/views/lesli_babel/partials/_engine-navigation.html.erb +37 -0
  59. data/app/views/lesli_babel/partials/_engine-sidebar.html.erb +45 -0
  60. data/app/views/lesli_babel/relevants/edit.html.erb +20 -0
  61. data/app/views/lesli_babel/relevants/index.html.erb +21 -0
  62. data/app/views/lesli_babel/relevants/new.html.erb +20 -0
  63. data/app/views/lesli_babel/relevants/show.html.erb +20 -0
  64. data/app/views/lesli_babel/string/activities/_form.html.erb +17 -0
  65. data/app/views/lesli_babel/string/activities/edit.html.erb +6 -0
  66. data/app/views/lesli_babel/string/activities/index.html.erb +25 -0
  67. data/app/views/lesli_babel/string/activities/new.html.erb +5 -0
  68. data/app/views/lesli_babel/string/activities/show.html.erb +4 -0
  69. data/app/views/lesli_babel/string/discussions/_form.html.erb +17 -0
  70. data/app/views/lesli_babel/string/discussions/edit.html.erb +6 -0
  71. data/app/views/lesli_babel/string/discussions/index.html.erb +25 -0
  72. data/app/views/lesli_babel/string/discussions/new.html.erb +5 -0
  73. data/app/views/lesli_babel/string/discussions/show.html.erb +4 -0
  74. data/app/views/lesli_babel/strings/_form.html.erb +17 -0
  75. data/app/views/lesli_babel/strings/edit.html.erb +6 -0
  76. data/app/views/lesli_babel/strings/index.html.erb +25 -0
  77. data/app/views/lesli_babel/strings/new.html.erb +5 -0
  78. data/app/views/lesli_babel/strings/show.html.erb +4 -0
  79. data/app/views/lesli_babel/translations/_form.html.erb +17 -0
  80. data/app/views/lesli_babel/translations/edit.html.erb +6 -0
  81. data/app/views/lesli_babel/translations/index.html.erb +1 -0
  82. data/app/views/lesli_babel/translations/new.html.erb +5 -0
  83. data/app/views/lesli_babel/translations/show.html.erb +1 -0
  84. data/config/routes.rb +63 -0
  85. data/db/migrate/v1.0/0901100110_create_lesli_babel_modules.rb +42 -0
  86. data/db/migrate/v1.0/0901110110_create_lesli_babel_buckets.rb +43 -0
  87. data/db/migrate/v1.0/0901120110_create_lesli_babel_strings.rb +80 -0
  88. data/lib/lesli_babel/engine.rb +54 -0
  89. data/lib/lesli_babel/version.rb +3 -0
  90. data/lib/lesli_babel.rb +6 -0
  91. data/lib/tasks/lesli_babel_tasks.rake +121 -0
  92. data/lib/vue/application.js +46 -0
  93. data/lib/vue/apps/dashboards/show.vue +85 -0
  94. data/lib/vue/apps/modules/show.vue +97 -0
  95. data/lib/vue/apps/relevants/index.vue +47 -0
  96. data/lib/vue/apps/translations/index.vue +64 -0
  97. data/lib/vue/components/actions.vue +29 -0
  98. data/lib/vue/components/form-label-editor.vue +439 -0
  99. data/lib/vue/components/form-string-new.vue +171 -0
  100. data/lib/vue/stores/module.js +49 -0
  101. data/lib/vue/stores/statistics.js +42 -0
  102. data/lib/vue/stores/strings.js +141 -0
  103. data/lib/vue/stores/translations.js +73 -0
  104. data/license +674 -0
  105. data/readme.md +19 -0
  106. metadata +149 -0
@@ -0,0 +1,134 @@
1
+ =begin
2
+
3
+ Lesli
4
+
5
+ Copyright (c) 2020, all rights reserved.
6
+
7
+ All the information provided by this platform is protected by international laws related to
8
+ industrial property, intellectual property, copyright and relative international laws.
9
+ All intellectual or industrial property rights of the code, texts, trade mark, design,
10
+ pictures and any other information belongs to the owner of this platform.
11
+
12
+ Without the written permission of the owner, any replication, modification,
13
+ transmission, publication is strictly forbidden.
14
+
15
+ For more information read the license file including with this software.
16
+
17
+ // · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
18
+ // ·
19
+
20
+ =end
21
+
22
+ module LesliBabel
23
+ class TranslationsController < ApplicationController
24
+ before_action :set_translation, only: []
25
+
26
+ # GET /translations
27
+ def index
28
+ #@translations = Translation.all
29
+ end
30
+
31
+ # GET /translations/1
32
+ def show
33
+ end
34
+
35
+ # GET /translations/new
36
+ def new
37
+ @translation = Translation.new
38
+ end
39
+
40
+ # GET /translations/1/edit
41
+ def edit
42
+ end
43
+
44
+ # POST /translations
45
+ def create
46
+ @translation = Translation.new(translation_params)
47
+
48
+ if @translation.save
49
+ redirect_to @translation, notice: "Translation was successfully created."
50
+ else
51
+ render :new
52
+ end
53
+ end
54
+
55
+ # PATCH/PUT /translations/1
56
+ def update
57
+ if @translation.update(translation_params)
58
+ redirect_to @translation, notice: "Translation was successfully updated."
59
+ else
60
+ render :edit
61
+ end
62
+ end
63
+
64
+ # DELETE /translations/1
65
+ def destroy
66
+ @translation.destroy
67
+ redirect_to translations_url, notice: "Translation was successfully destroyed."
68
+ end
69
+
70
+ def options
71
+ respond_with_successful({
72
+ locales_available: Lesli.config.locales
73
+ })
74
+ end
75
+
76
+ def clean
77
+ respond_with_successful()
78
+ end
79
+
80
+ def deploy
81
+ #TranslationsService.clean
82
+ TranslationsRailsService.build
83
+ TranslationsService.restart_server
84
+ respond_with_successful
85
+ end
86
+
87
+ def renovate
88
+ result = TranslationsSynchronizationService.remote_sync
89
+ respond_with_successful if result.success?
90
+ respond_with_error if not result.success?
91
+ end
92
+
93
+ def sync
94
+ result = TranslationsSynchronizationService.remote_sync true
95
+ respond_with_successful if result.success?
96
+ respond_with_error if not result.success?
97
+ end
98
+
99
+ def download
100
+
101
+ engine = params[:engine]
102
+ platform = params[:platform]
103
+
104
+ translations_result = TranslationsMiddlemanService.build(engine) if platform == "middleman"
105
+ translations_result = TranslationsAndroidService.build(engine) if platform == "android"
106
+ translations_result = TranslationsFlutterService.build(engine) if platform == "flutter"
107
+ translations_result = TranslationsIosService.build(engine) if platform == "ios"
108
+ translations_result = TranslationsJsService.build() if platform == "js"
109
+
110
+ return respond_with_error if translations_result.blank?
111
+
112
+ zip_file = "#{platform}-#{engine}-translations.zip"
113
+
114
+ LC::System::IO.zip(zip_file, translations_result.payload)
115
+
116
+ redirect_to "/tmp/#{zip_file}"
117
+
118
+ end
119
+
120
+
121
+ private
122
+
123
+ # Use callbacks to share common setup or constraints between actions.
124
+ def set_translation
125
+ @translation = Translation.find(params[:id])
126
+ end
127
+
128
+ # Only allow a trusted parameter "white list" through.
129
+ def translation_params
130
+ params.fetch(:translation, {})
131
+ end
132
+
133
+ end
134
+ end
@@ -0,0 +1,7 @@
1
+ module LesliBabel
2
+ class ApplicationJob < ActiveJob::Base
3
+ def perform()
4
+
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,6 @@
1
+ module LesliBabel
2
+ class ApplicationMailer < ActionMailer::Base
3
+ default from: 'from@example.com'
4
+ layout 'mailer'
5
+ end
6
+ end
@@ -0,0 +1,36 @@
1
+ =begin
2
+
3
+ Lesli
4
+
5
+ Copyright (c) 2023, Lesli Technologies, S. A.
6
+
7
+ This program is free software: you can redistribute it and/or modify
8
+ it under the terms of the GNU General Public License as published by
9
+ the Free Software Foundation, either version 3 of the License, or
10
+ (at your option) any later version.
11
+
12
+ This program is distributed in the hope that it will be useful,
13
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ GNU General Public License for more details.
16
+
17
+ You should have received a copy of the GNU General Public License
18
+ along with this program. If not, see http://www.gnu.org/licenses/.
19
+
20
+ Lesli · Ruby on Rails SaaS Development Framework.
21
+
22
+ Made with ♥ by https://www.lesli.tech
23
+ Building a better future, one line of code at a time.
24
+
25
+ @contact hello@lesli.tech
26
+ @website https://www.lesli.tech
27
+ @license GPLv3 http://www.gnu.org/licenses/gpl-3.0.en.html
28
+
29
+ // · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
30
+ // ·
31
+ =end
32
+ module LesliBabel
33
+ class ApplicationRecord < Lesli::ApplicationLesliRecord
34
+ self.abstract_class = true
35
+ end
36
+ end
@@ -0,0 +1,6 @@
1
+ module LesliBabel
2
+ class Bucket < ApplicationRecord
3
+ belongs_to :module
4
+ has_many :strings
5
+ end
6
+ end
@@ -0,0 +1,24 @@
1
+ =begin
2
+
3
+ Copyright (c) 2021, all rights reserved.
4
+
5
+ All the information provided by this platform is protected by international laws related to
6
+ industrial property, intellectual property, copyright and relative international laws.
7
+ All intellectual or industrial property rights of the code, texts, trade mark, design,
8
+ pictures and any other information belongs to the owner of this platform.
9
+
10
+ Without the written permission of the owner, any replication, modification,
11
+ transmission, publication is strictly forbidden.
12
+
13
+ For more information read the license file including with this software.
14
+
15
+ // · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
16
+ // ·
17
+
18
+ =end
19
+
20
+ module LesliBabel
21
+ class Clone < ApplicationLesliRecord
22
+
23
+ end
24
+ end
@@ -0,0 +1,35 @@
1
+ =begin
2
+
3
+ Lesli
4
+
5
+ Copyright (c) 2023, Lesli Technologies, S. A.
6
+
7
+ This program is free software: you can redistribute it and/or modify
8
+ it under the terms of the GNU General Public License as published by
9
+ the Free Software Foundation, either version 3 of the License, or
10
+ (at your option) any later version.
11
+
12
+ This program is distributed in the hope that it will be useful,
13
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ GNU General Public License for more details.
16
+
17
+ You should have received a copy of the GNU General Public License
18
+ along with this program. If not, see http://www.gnu.org/licenses/.
19
+
20
+ Lesli · Ruby on Rails SaaS Development Framework.
21
+
22
+ Made with ♥ by https://www.lesli.tech
23
+ Building a better future, one line of code at a time.
24
+
25
+ @contact hello@lesli.tech
26
+ @website https://www.lesli.tech
27
+ @license GPLv3 http://www.gnu.org/licenses/gpl-3.0.en.html
28
+
29
+ // · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
30
+ // ·
31
+ =end
32
+ module LesliBabel
33
+ class Dashboard < ApplicationRecord
34
+ end
35
+ end
@@ -0,0 +1,35 @@
1
+ module LesliBabel
2
+ class Module < ApplicationRecord
3
+ has_many :buckets
4
+
5
+ validates_presence_of :platform
6
+
7
+ before_create :format_module_name
8
+
9
+ def self.index
10
+ Module.where("name is not null")
11
+ order(id: :desc).map do |translation_module|
12
+ {
13
+ id: translation_module[:id],
14
+ name: translation_module[:name],
15
+ code: translation_module[:name].downcase,
16
+ platform: translation_module[:platform]
17
+ }
18
+ end
19
+ end
20
+
21
+ def format_module_name
22
+
23
+ return if self.platform == "lesli_core"
24
+ return if self.platform == "lesli_engine"
25
+
26
+ self.name = self.name
27
+ .gsub(/[^0-9A-Za-z\s\-\_]/, '') # remove special characters from string
28
+ .gsub(/-/, '') # replace dashes with underscore
29
+ .gsub(/_/, '') # replace underscore with underscore
30
+ .titlecase # Capitalizes all the words
31
+ .gsub(/\s+/, '') # remove blank spaces
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,21 @@
1
+ =begin
2
+ Copyright (c) 2023, all rights reserved.
3
+
4
+ All the information provided by this platform is protected by international laws related to
5
+ industrial property, intellectual property, copyright and relative international laws.
6
+ All intellectual or industrial property rights of the code, texts, trade mark, design,
7
+ pictures and any other information belongs to the owner of this platform.
8
+
9
+ Without the written permission of the owner, any replication, modification,
10
+ transmission, publication is strictly forbidden.
11
+
12
+ For more information read the license file including with this software.
13
+
14
+ // · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
15
+ // ·
16
+
17
+ =end
18
+ module LesliBabel
19
+ class Relevant < ApplicationRecord
20
+ end
21
+ end
@@ -0,0 +1,5 @@
1
+ module LesliBabel
2
+ class String::Activity < CloudObject::Activity
3
+ belongs_to :cloud_object, class_name: "String", foreign_key: "cloud_babel_strings_id", optional: true
4
+ end
5
+ end
@@ -0,0 +1,68 @@
1
+ module LesliBabel
2
+ class String::Discussion < CloudObject::Discussion
3
+ belongs_to :cloud_object, class_name: "String", foreign_key: "cloud_babel_strings_id"
4
+ belongs_to :parent, class_name: "Discussion", optional: true
5
+ has_many :children, class_name: "Discussion", foreign_key: "parent_id"
6
+
7
+ def self.list(current_user, cloud_id)
8
+
9
+ discussions = self.joins(
10
+ "inner join cloud_babel_strings CO on cloud_babel_string_discussions.cloud_babel_strings_id = CO.id"
11
+ ).joins(
12
+ "inner join users U on cloud_babel_string_discussions.users_id = U.id"
13
+ ).joins(
14
+ "inner join user_details UD on UD.users_id = U.id"
15
+ ).select(
16
+ "cloud_babel_string_discussions.id",
17
+ "cloud_babel_string_discussions.users_id",
18
+ "cloud_babel_string_discussions.content",
19
+ "cloud_babel_string_discussions.created_at",
20
+ "cloud_babel_string_discussions.cloud_babel_string_discussions_id",
21
+ "U.email",
22
+ "CONCAT(UD.first_name, ' ', UD.last_name) as user_name"
23
+ )
24
+ .where("CO.id = #{cloud_id}")
25
+ .where("CO.reference_module_bucket LIKE ?", "#{Rails.configuration.lesli_settings["instance"]}%")
26
+ .order(id: :asc)
27
+ .map { |discussion|
28
+ discussion_attributes = discussion.attributes
29
+ discussion_attributes["created_at_raw"] = discussion_attributes["created_at"]
30
+ discussion_attributes["editable"] = discussion.is_editable_by?(current_user)
31
+ discussion_attributes["created_at"] = LC::Date.to_string_datetime(discussion_attributes["created_at"])
32
+ discussion_attributes
33
+ }
34
+
35
+ data = {}
36
+ root_discussions = []
37
+
38
+ # Add all responses to that discussion
39
+ discussions.each do |discussion|
40
+ discussion_data = {
41
+ data: discussion,
42
+ responses: []
43
+ }
44
+ data[discussion["id"]] = discussion_data
45
+
46
+ if discussion["cloud_babel_string_discussions_id"].present?
47
+ parent_discussion = data[discussion["cloud_babel_string_discussions_id"]]
48
+ if parent_discussion[:data]["cloud_babel_string_discussions_id"].present?
49
+ discussion["response_to"] = parent_discussion[:data]["email"]
50
+ end
51
+ parent_discussion[:responses].push(discussion["id"])
52
+ else
53
+ root_discussions.push(discussion_data)
54
+ end
55
+ end
56
+
57
+ # Nest the responses to root discussions. A root discussion is any comment that is not a response to another comment
58
+ root_discussions.each do |discussion|
59
+ responses = []
60
+ self.nest_responses(data, discussion, responses)
61
+ discussion[:responses] = responses
62
+ end
63
+
64
+ # revert the root discussions so the most recent comments appear in the top
65
+ root_discussions.reverse
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,225 @@
1
+ module LesliBabel
2
+ class String < ApplicationRecord
3
+ belongs_to :user
4
+ belongs_to :bucket
5
+
6
+ before_create :clean_label_string
7
+
8
+ def self.index(current_user, query, params)
9
+
10
+ strings = TranslationsService.strings(params[:module], params[:bucket])
11
+
12
+ # if search string was sent
13
+ if params[:search]
14
+
15
+ search = params[:search].downcase.gsub(" ","%")
16
+
17
+ sql_where_condition = []
18
+
19
+ # add filter to select only available languages
20
+ Rails.application.config.lesli_settings["configuration"]["locales"].each do |locale|
21
+ sql_where_condition.push("LOWER(#{locale}) like :search")
22
+ end
23
+
24
+ sql_where_condition.push("LOWER(label) like :search")
25
+ sql_where_condition.push("LOWER(context) like :search")
26
+
27
+ # get strings with bucket and module information
28
+ strings = strings.where(sql_where_condition.join(" OR "), { search: "%#{ search }%" })
29
+
30
+ end
31
+
32
+ # filters by specif ids sent as query params
33
+ if params["ids"]
34
+ ids = params["ids"].split(',').map{ |id| id.to_i }
35
+ strings = strings.where("cloud_babel_strings.id in (?)", ids)
36
+ end
37
+
38
+ strings = strings.select(
39
+ :id,
40
+ :label,
41
+ :status,
42
+ :context,
43
+ :priority,
44
+ :need_help,
45
+ :need_translation,
46
+ Rails.application.config.lesli_settings["configuration"]["locales"],
47
+ "cloud_babel_modules.id as engine_id",
48
+ "cloud_babel_buckets.id as bucket_id",
49
+ "cloud_babel_buckets.name as bucket_name",
50
+ "cloud_babel_modules.name as engine_name",
51
+ "cloud_babel_modules.platform as platform",
52
+ "'' as path"
53
+ )
54
+
55
+ strings = strings
56
+ .page(query[:pagination][:page])
57
+ .per(query[:pagination][:perPage])
58
+ .order(:updated_at)
59
+
60
+ end
61
+
62
+
63
+ def self.relevant current_user, query, params
64
+ # relevant strings:
65
+ # - missing translation for available language
66
+ # - need help
67
+ # - need translation
68
+
69
+ locale = query.dig(:order, :by)
70
+ strings = []
71
+ sql_where_condition = []
72
+
73
+ # add filter to select if is available language
74
+ if locale
75
+ if Rails.application.config.lesli.dig(:configuration, :locales).include?(locale.to_s)
76
+ sql_where_condition.push("#{locale.to_s} is NULL")
77
+ sql_where_condition.push("#{locale.to_s} = ''")
78
+ end
79
+ else
80
+ Rails.application.config.lesli.dig(:configuration, :locales).each do |locale|
81
+ sql_where_condition.push("#{locale} is NULL")
82
+ sql_where_condition.push("#{locale} = ''")
83
+ end
84
+ end
85
+
86
+ sql_where_condition.push("need_help = TRUE")
87
+ sql_where_condition.push("need_translation = TRUE")
88
+
89
+ strings = TranslationsService.strings.where(sql_where_condition.join(" OR ")).select(
90
+ :id,
91
+ :label,
92
+ :status,
93
+ :context,
94
+ :priority,
95
+ :need_help,
96
+ :need_translation,
97
+ Rails.application.config.lesli_settings["configuration"]["locales"],
98
+ "cloud_babel_modules.id as engine_id",
99
+ "cloud_babel_buckets.id as bucket_id",
100
+ "cloud_babel_buckets.name as bucket_name",
101
+ "cloud_babel_modules.name as engine_name",
102
+ "cloud_babel_modules.platform as platform",
103
+ "'' as path"
104
+ )
105
+
106
+ strings
107
+ .page(query[:pagination][:page])
108
+ .per(query[:pagination][:perPage])
109
+ .order(query.dig(:order, :by))
110
+
111
+ end
112
+
113
+
114
+
115
+ #######################################################################################
116
+ ############################## Activities Log Methods ##############################
117
+ #######################################################################################
118
+
119
+ # @return [void]
120
+ # @param current_user [::User] The user that created the string
121
+ # @param [CloudBabel::String] The string that was created
122
+ # @description Creates an activity for this string indicating who created it. And
123
+ # also creates an activity with the initial status of the string
124
+ # Example
125
+ # params = {...}
126
+ # string = CloudBabel::String.create(params)
127
+ # CloudBabel::String.log_activity_create(User.find(1), string)
128
+ def self.log_activity_create(current_user, string)
129
+ string.activities.create(
130
+ user_creator: current_user,
131
+ category: "action_create",
132
+ reference_module_bucket_string: "#{string.reference_module_bucket}-#{string.label}"
133
+ )
134
+ end
135
+
136
+ # @return [void]
137
+ # @param current_user [::User] The user that created the string
138
+ # @param string [CloudBabel::String] The string that was created
139
+ # @param old_attributes[Hash] The data of the record before update
140
+ # @param new_attributes[Hash] The data of the record after update
141
+ # @description Creates an activity for this string if someone changed any of this values
142
+ # Example
143
+ # string = CloudBabel::String.find(1)
144
+ # old_attributes = string.attributes.merge({detail_attributes: string.detail.attributes})
145
+ # string.update(user_main: User.find(33))
146
+ # new_attributes = string.attributes.merge({detail_attributes: string.detail.attributes})
147
+ # CloudBabel::String.log_activity_update(User.find(1), string, old_attributes, new_attributes)
148
+ def self.log_activity_update(current_user, string, old_attributes, new_attributes)
149
+ # Bucket is a special case because it's a foreign key
150
+ if old_attributes["cloud_babel_buckets_id"] != new_attributes["cloud_babel_buckets_id"]
151
+ string.activities.create(
152
+ user_creator: current_user,
153
+ category: "action_update",
154
+ field_name: "cloud_babel_buckets_id",
155
+ value_from: Bucket.find(old_attributes["cloud_babel_buckets_id"]).name,
156
+ value_to: Bucket.find(new_attributes["cloud_babel_buckets_id"]).name
157
+ )
158
+ end
159
+
160
+ # We exclude certain keys that are not relevant
161
+ old_attributes.except!("id", "cloud_babe_buckets_id", "created_at", "updated_at", "deleted_at", "users_id")
162
+
163
+ old_attributes.each do |key, value|
164
+ if value != new_attributes[key]
165
+ value_from = value
166
+ value_to = new_attributes[key]
167
+ value_from = LC::Date.to_string_datetime(value_from) if value_from.is_a?(Time) || value_from.is_a?(Date)
168
+ value_to = LC::Date.to_string_datetime(value_to) if value_to.is_a?(Time) || value_to.is_a?(Date)
169
+
170
+ string.activities.create(
171
+ user_creator: current_user,
172
+ category: "action_update",
173
+ field_name: key,
174
+ value_from: value_from,
175
+ value_to: value_to,
176
+ reference_module_bucket_string: "#{string.reference_module_bucket}-#{string.label}"
177
+ )
178
+ end
179
+ end
180
+ end
181
+
182
+ # @return [void]
183
+ # @param current_user [::User] The user that created the string
184
+ # @param [CloudBabel::String] The string that was created
185
+ # @description Creates an activity for this string indicating that someone deleted it
186
+ # Example
187
+ # string = CloudBabel::String.find(1)
188
+ # CloudBabel::String.log_activity_show(User.find(1), string)
189
+ def self.log_activity_destroy(current_user, string)
190
+ string.activities.create(
191
+ user_creator: current_user,
192
+ category: "action_destroy",
193
+ reference_module_bucket_string: "#{string.reference_module_bucket}-#{string.label}"
194
+ )
195
+ end
196
+
197
+ def path
198
+ self[:engine_name]
199
+ .downcase
200
+ .sub("cloud", "")
201
+ .concat(".")
202
+ .concat(self[:bucket_name])
203
+ .concat(".")
204
+ .concat(self[:label])
205
+ end
206
+
207
+ private
208
+
209
+ def clean_label_string
210
+
211
+ self.label = self.label
212
+ .downcase # string to lowercase
213
+ .gsub(/[^0-9A-Za-z\s\-\_]/, '') # remove special characters from string
214
+ .gsub(/-/, '_') # replace dashes with underscore
215
+ .gsub(/\s+/, '_') # replace spaces or spaces with single dash
216
+
217
+ self.status = "normal" if self.status.blank?
218
+ self.priority = "normal" if self.priority.blank?
219
+
220
+ self.reference_module_bucket = "#{self.bucket.reference_module}-#{self.bucket.name}"
221
+
222
+ end
223
+
224
+ end
225
+ end
@@ -0,0 +1,5 @@
1
+ module LesliBabel
2
+ class Translation < ApplicationRecord
3
+
4
+ end
5
+ end
@@ -0,0 +1,18 @@
1
+ module LesliBabel
2
+ class ModuleService < Lesli::ApplicationLesliService
3
+
4
+ def list
5
+
6
+ # get the list of installed engines, including: rails_core, rails_builder, rails_engine
7
+ babel_modules_names = Lesli::System.engines.map { |engine, engine_info| engine_info[:code] }
8
+
9
+ # get list of ids of installed engines and available third-party apps
10
+ Module
11
+ .where(:name => babel_modules_names) # -> only installed engines
12
+ #.or(Module.where.not(:platform => ["rails_core", "rails_builder", "rails_engine"]))
13
+ .map { |engine| engine.id }
14
+
15
+ end
16
+
17
+ end
18
+ end