lesli_babel 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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