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.
- checksums.yaml +7 -0
- data/Rakefile +5 -0
- data/app/assets/config/lesli_babel_manifest.js +7 -0
- data/app/assets/images/lesli_babel/babel-logo.svg +157 -0
- data/app/assets/javascripts/lesli_babel/application.js +3288 -0
- data/app/assets/stylesheets/lesli_babel/application.scss +41 -0
- data/app/assets/stylesheets/lesli_babel/dashboards.scss +55 -0
- data/app/assets/stylesheets/lesli_babel/modules.scss +33 -0
- data/app/assets/stylesheets/lesli_babel/translations.scss +58 -0
- data/app/controllers/lesli_babel/application_controller.rb +37 -0
- data/app/controllers/lesli_babel/buckets_controller.rb +79 -0
- data/app/controllers/lesli_babel/clones_controller.rb +80 -0
- data/app/controllers/lesli_babel/dashboards_controller.rb +38 -0
- data/app/controllers/lesli_babel/modules_controller.rb +91 -0
- data/app/controllers/lesli_babel/relevants_controller.rb +38 -0
- data/app/controllers/lesli_babel/strings_controller.rb +142 -0
- data/app/controllers/lesli_babel/translations_controller.rb +134 -0
- data/app/jobs/lesli_babel/application_job.rb +7 -0
- data/app/mailers/lesli_babel/application_mailer.rb +6 -0
- data/app/models/lesli_babel/application_record.rb +36 -0
- data/app/models/lesli_babel/bucket.rb +6 -0
- data/app/models/lesli_babel/clone.rb +24 -0
- data/app/models/lesli_babel/dashboard.rb +35 -0
- data/app/models/lesli_babel/module.rb +35 -0
- data/app/models/lesli_babel/relevant.rb +21 -0
- data/app/models/lesli_babel/string/activity.rb +5 -0
- data/app/models/lesli_babel/string/discussion.rb +68 -0
- data/app/models/lesli_babel/string.rb +225 -0
- data/app/models/lesli_babel/translation.rb +5 -0
- data/app/services/lesli_babel/module_service.rb +18 -0
- data/app/services/lesli_babel/old/translations_android_service.rb +82 -0
- data/app/services/lesli_babel/old/translations_clone_service.rb +161 -0
- data/app/services/lesli_babel/old/translations_flutter_service.rb +102 -0
- data/app/services/lesli_babel/old/translations_ios_service.rb +119 -0
- data/app/services/lesli_babel/old/translations_js_service.rb +114 -0
- data/app/services/lesli_babel/old/translations_middleman_service.rb +77 -0
- data/app/services/lesli_babel/old/translations_rails_service.rb +119 -0
- data/app/services/lesli_babel/old/translations_service.rb +97 -0
- data/app/services/lesli_babel/old/translations_synchronization_service.rb +215 -0
- data/app/services/lesli_babel/string_service.rb +80 -0
- data/app/views/lesli_babel/buckets/_form.html.erb +17 -0
- data/app/views/lesli_babel/buckets/edit.html.erb +6 -0
- data/app/views/lesli_babel/buckets/index.html.erb +25 -0
- data/app/views/lesli_babel/buckets/new.html.erb +5 -0
- data/app/views/lesli_babel/buckets/show.html.erb +4 -0
- data/app/views/lesli_babel/clones/_form.html.erb +19 -0
- data/app/views/lesli_babel/clones/edit.html.erb +20 -0
- data/app/views/lesli_babel/clones/index.html.erb +20 -0
- data/app/views/lesli_babel/clones/new.html.erb +20 -0
- data/app/views/lesli_babel/clones/show.html.erb +20 -0
- data/app/views/lesli_babel/dashboards/show.html.erb +1 -0
- data/app/views/lesli_babel/dashboards/stats..html.erb +1 -0
- data/app/views/lesli_babel/modules/_form.html.erb +17 -0
- data/app/views/lesli_babel/modules/edit.html.erb +1 -0
- data/app/views/lesli_babel/modules/index.html.erb +1 -0
- data/app/views/lesli_babel/modules/new.html.erb +1 -0
- data/app/views/lesli_babel/modules/show.html.erb +1 -0
- data/app/views/lesli_babel/partials/_engine-navigation.html.erb +37 -0
- data/app/views/lesli_babel/partials/_engine-sidebar.html.erb +45 -0
- data/app/views/lesli_babel/relevants/edit.html.erb +20 -0
- data/app/views/lesli_babel/relevants/index.html.erb +21 -0
- data/app/views/lesli_babel/relevants/new.html.erb +20 -0
- data/app/views/lesli_babel/relevants/show.html.erb +20 -0
- data/app/views/lesli_babel/string/activities/_form.html.erb +17 -0
- data/app/views/lesli_babel/string/activities/edit.html.erb +6 -0
- data/app/views/lesli_babel/string/activities/index.html.erb +25 -0
- data/app/views/lesli_babel/string/activities/new.html.erb +5 -0
- data/app/views/lesli_babel/string/activities/show.html.erb +4 -0
- data/app/views/lesli_babel/string/discussions/_form.html.erb +17 -0
- data/app/views/lesli_babel/string/discussions/edit.html.erb +6 -0
- data/app/views/lesli_babel/string/discussions/index.html.erb +25 -0
- data/app/views/lesli_babel/string/discussions/new.html.erb +5 -0
- data/app/views/lesli_babel/string/discussions/show.html.erb +4 -0
- data/app/views/lesli_babel/strings/_form.html.erb +17 -0
- data/app/views/lesli_babel/strings/edit.html.erb +6 -0
- data/app/views/lesli_babel/strings/index.html.erb +25 -0
- data/app/views/lesli_babel/strings/new.html.erb +5 -0
- data/app/views/lesli_babel/strings/show.html.erb +4 -0
- data/app/views/lesli_babel/translations/_form.html.erb +17 -0
- data/app/views/lesli_babel/translations/edit.html.erb +6 -0
- data/app/views/lesli_babel/translations/index.html.erb +1 -0
- data/app/views/lesli_babel/translations/new.html.erb +5 -0
- data/app/views/lesli_babel/translations/show.html.erb +1 -0
- data/config/routes.rb +63 -0
- data/db/migrate/v1.0/0901100110_create_lesli_babel_modules.rb +42 -0
- data/db/migrate/v1.0/0901110110_create_lesli_babel_buckets.rb +43 -0
- data/db/migrate/v1.0/0901120110_create_lesli_babel_strings.rb +80 -0
- data/lib/lesli_babel/engine.rb +54 -0
- data/lib/lesli_babel/version.rb +3 -0
- data/lib/lesli_babel.rb +6 -0
- data/lib/tasks/lesli_babel_tasks.rake +121 -0
- data/lib/vue/application.js +46 -0
- data/lib/vue/apps/dashboards/show.vue +85 -0
- data/lib/vue/apps/modules/show.vue +97 -0
- data/lib/vue/apps/relevants/index.vue +47 -0
- data/lib/vue/apps/translations/index.vue +64 -0
- data/lib/vue/components/actions.vue +29 -0
- data/lib/vue/components/form-label-editor.vue +439 -0
- data/lib/vue/components/form-string-new.vue +171 -0
- data/lib/vue/stores/module.js +49 -0
- data/lib/vue/stores/statistics.js +42 -0
- data/lib/vue/stores/strings.js +141 -0
- data/lib/vue/stores/translations.js +73 -0
- data/license +674 -0
- data/readme.md +19 -0
- 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,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,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,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,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
|