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,119 @@
1
+ module LesliBabel
2
+ class TranslationsRailsService
3
+
4
+ def self.build
5
+
6
+ engines_installed = Rails.application.config.lesli_settings["engines"].map do |engine|
7
+ engine[:name]
8
+ end
9
+
10
+ # get all rails engines to buil
11
+ engines = Module
12
+ .where("platform in ('rails_core', 'rails_builder', 'rails_engine', 'standard')")
13
+ .where("name in (?)", engines_installed.push("Core","LesliMails"))
14
+ .map do |engine|
15
+ engine[:id]
16
+ end
17
+
18
+ # get strings filtered by module (only rails translations)
19
+ strings = TranslationsService.strings(engines)
20
+
21
+ strings = strings.select(
22
+ :id,
23
+ :label,
24
+ :status,
25
+ :context,
26
+ :priority,
27
+ :need_help,
28
+ :need_translation,
29
+ Rails.application.config.lesli_settings["configuration"]["locales"],
30
+ "cloud_babel_modules.id as engine_id",
31
+ "cloud_babel_buckets.id as bucket_id",
32
+ "cloud_babel_buckets.name as bucket_name",
33
+ "cloud_babel_modules.name as engine_name",
34
+ "cloud_babel_modules.platform as platform",
35
+ "'' as path"
36
+ )
37
+
38
+ translations = {}
39
+
40
+ available_locales = Rails.application.config.lesli_settings["configuration"]["locales"]
41
+
42
+ # add key for every available language (required by i18n Rails gem)
43
+ available_locales.each do |lang|
44
+ translations[lang] = { }
45
+ end
46
+
47
+ strings.each do |string|
48
+ module_name = string[:engine_name].downcase.sub("cloud", "")
49
+ engine_code = string[:engine_name].underscore
50
+ engine_name = string[:engine_name]
51
+ bucket_name = string[:bucket_name]
52
+ platform = string[:platform]
53
+
54
+ available_locales.each do |lang|
55
+
56
+ # translations path for lesli core
57
+ file_path = Rails.root.join("config", "locales", bucket_name, "#{ bucket_name.gsub("/","_") }.#{ lang }.yml")
58
+
59
+ # translations path for translations for engines
60
+ if platform == "rails_builder" || platform == "rails_engine" || platform == "standard"
61
+ file_path = Rails.root.join("engines", engine_name, "config", "locales", bucket_name, "#{ bucket_name }.#{ lang }.yml")
62
+ file_path = Rails.root.join("config", "locales", engine_code, bucket_name, "#{ bucket_name.gsub("/","_") }.#{ lang }.yml")
63
+ end
64
+
65
+ file_id = file_path.to_s.to_sym
66
+
67
+ unless translations[lang].has_key? file_id
68
+ translations[lang][file_id] = { }
69
+ end
70
+
71
+ unless translations[lang][file_id].has_key? module_name
72
+ translations[lang][file_id][module_name] = { }
73
+ end
74
+
75
+ unless translations[lang][file_id][module_name].has_key? bucket_name
76
+ translations[lang][file_id][module_name][bucket_name] = { }
77
+ end
78
+
79
+ # send debug message for missing translations
80
+ string[lang] = ":" + string.path + ":" if string[lang].blank?
81
+
82
+ translations[lang][file_id][module_name][bucket_name][string.label] = string[lang]
83
+
84
+ end
85
+
86
+ end
87
+
88
+ translations.each do |file_by_language|
89
+
90
+ lang = file_by_language[0]
91
+ file_by_controller = file_by_language[1]
92
+
93
+ file_by_controller.each do |file|
94
+
95
+ file_path = file[0].to_s
96
+ translations = file[1]
97
+
98
+ # creates folder and subfolders
99
+ FileUtils.makedirs(File.dirname(file_path))
100
+
101
+ # creates translation file for every available language
102
+ translation_file = File.new(file_path, "w+")
103
+
104
+ translation_file.write({ "#{lang}": translations}.to_yaml)
105
+
106
+ translation_file.close
107
+
108
+ p "file added: #{ file_path }"
109
+
110
+ end
111
+
112
+ end
113
+
114
+ LC::Response.service true, translations
115
+
116
+ end
117
+
118
+ end
119
+ end
@@ -0,0 +1,97 @@
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
+ module LesliBabel
22
+ class TranslationsService
23
+
24
+ def self.restart_server
25
+ return if Rails.env != "production"
26
+ system "bundle exec rake i18n:js:export RAILS_ENV=production"
27
+ FileUtils.touch Rails.root.join("tmp", "restart.txt")
28
+ end
29
+
30
+ def self.clean
31
+
32
+ # store full path to translation files for every language
33
+ files_to_delete = []
34
+
35
+ # remove javascript translation cache
36
+ files_to_delete.push(Rails.root.join("public", "javascripts", "translations.js"))
37
+
38
+ # get translation files for engines only
39
+ Lesli::engines.each do |engine|
40
+ files_to_delete.push(Rails.root.join("engines", engine["name"], "config", "locales"))
41
+ end
42
+
43
+ # include translation files for lesli core
44
+ files_to_delete.push(Rails.root.join("config", "locales"))
45
+
46
+ # include external app translations
47
+ files_to_delete.push(Rails.root.join("public", "tmp", "locales"))
48
+
49
+ # delete all the translation files found
50
+ files_to_delete.each do |file|
51
+ FileUtils.rm_rf(file)
52
+ end
53
+
54
+ LC::Response.service true, files_to_delete
55
+
56
+ end
57
+
58
+ def self.strings engines_id=nil, buckets_id=nil
59
+
60
+ # get strings with bucket and module information
61
+ strings = String
62
+ .joins("inner join cloud_babel_buckets on cloud_babel_buckets.id = cloud_babel_strings.cloud_babel_buckets_id and cloud_babel_buckets.deleted_at is NULL")
63
+ .joins("inner join cloud_babel_modules on cloud_babel_modules.id = cloud_babel_buckets.cloud_babel_modules_id and cloud_babel_modules.deleted_at is NULL")
64
+ .where("cloud_babel_modules.id in (?)", TranslationsService.installed_engines_id)
65
+
66
+ # filter by specific engines
67
+ if engines_id
68
+ strings = strings.where("cloud_babel_modules.id in (?)", engines_id)
69
+ end
70
+
71
+ # filter by specific engine buckets
72
+ if buckets_id
73
+ strings = strings.where("cloud_babel_buckets.id in (?)", buckets_id)
74
+ end
75
+
76
+ strings
77
+
78
+ end
79
+
80
+ def self.strings_for_apps engines_id=nil, buckets_id=nil
81
+
82
+ strings = strings(engines_id, buckets_id)
83
+ strings = strings.select(
84
+ :id,
85
+ :label,
86
+ "cloud_babel_modules.name as engine_name",
87
+ "cloud_babel_buckets.name as bucket_name",
88
+ "cloud_babel_modules.platform",
89
+ Rails.application.config.lesli_settings["configuration"]["locales"]
90
+ )
91
+
92
+ strings
93
+
94
+ end
95
+
96
+ end
97
+ end
@@ -0,0 +1,215 @@
1
+ =begin
2
+
3
+ Copyright (c) 2020, 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 TranslationsSynchronizationService
22
+
23
+ # IMPORTANT: If you modify this file please check the CloneService that contains a modified
24
+ # copy of this synchronization code
25
+ def self.remote_sync double_way_sync=false
26
+
27
+ host = "http://localhost:8080"
28
+ host = "https://api.datenbanken.dev/v2"
29
+ instance_code = LC::System::Info.instance[:code].gsub("_","-")
30
+
31
+ # if special namespace is configured in the lesli.yml settings
32
+ # this is useful when we need install an instance and customize
33
+ # the translations for a client
34
+ #instance_code = Rails.application.config.lesli.dig(:configuration, :babel, :namespace)
35
+
36
+ api_endpoint = "#{host}/buckets/#{instance_code}-babel/documents"
37
+
38
+
39
+ # get last sync data
40
+ response = Faraday.get("#{api_endpoint}/last")
41
+ response = FastJsonparser.parse(response.body)
42
+ response = response[:documents][0]
43
+
44
+ # if first time sync
45
+ response = FastJsonparser.parse({ modules: [], buckets: [], strings: [] }.to_json) if response.blank?
46
+
47
+ # add new modules
48
+ response[:modules].each do |babel_module|
49
+ next if babel_module[:name].blank?
50
+
51
+ local_module = CloudBabel::Module
52
+ .create_with({
53
+ created_at: babel_module[:created_at],
54
+ platform: babel_module[:platform]
55
+ }).find_or_create_by({ name: babel_module[:name] })
56
+
57
+ platform = babel_module[:platform]
58
+ platform = "rails_engine" if babel_module[:name].start_with?("Cloud")
59
+ platform = "rails_core" if babel_module[:name] == "Core"
60
+ platform = "rails_builder" if ["MitwerkenCloud", "DeutscheLeibrenten", "LesliCloud"].include?(babel_module[:name])
61
+
62
+ local_module.platform = platform
63
+ local_module.updated_at = DateTime.now
64
+ local_module.save
65
+
66
+ end
67
+
68
+ # working with buckets
69
+ babel_reference_modules = {}
70
+
71
+ response[:buckets].each do |babel_bucket|
72
+
73
+ next if babel_bucket[:name].blank?
74
+
75
+ # reference to modules that buckets belongs to
76
+ # this reference as string is necessary because the id of the module can change
77
+ # between synchronizations, thats why we search for the id of the module every time
78
+ if babel_reference_modules[babel_bucket[:reference_module]].blank?
79
+ babel_reference_modules[babel_bucket[:reference_module]] =
80
+ CloudBabel::Module.find_by(name: babel_bucket[:reference_module])
81
+ end
82
+
83
+ # add new bucket
84
+ CloudBabel::Bucket
85
+ .create_with({
86
+ created_at: babel_bucket[:created_at],
87
+ module: babel_reference_modules[babel_bucket[:reference_module]]
88
+ }).find_or_create_by({
89
+ name: babel_bucket[:name],
90
+ reference_module: babel_bucket[:reference_module]
91
+ })
92
+
93
+ end
94
+
95
+ # · working with strings
96
+ babel_reference_buckets = {}
97
+
98
+ response[:strings].each do |remote_string|
99
+ # reference to modules that buckets belongs to
100
+ # this reference as string is necessary because the id of the module or bucket can change
101
+ # between synchronizations, thats why we search for the id of the module every time
102
+ if babel_reference_buckets[remote_string[:reference_bucket]].blank?
103
+ remote_string[:reference_bucket] ||= remote_string[:reference_module_bucket]
104
+ babel_reference_buckets[remote_string[:reference_bucket]] =
105
+ CloudBabel::Bucket.find_by(
106
+ name: remote_string[:reference_bucket].split("-")[1],
107
+ reference_module: remote_string[:reference_bucket].split("-")[0]
108
+ )
109
+ end
110
+
111
+ # Do not sync labes that do not have a valid module and bucket reference
112
+ next if babel_reference_buckets[remote_string[:reference_bucket]].blank?
113
+
114
+ remote_string_reference = "#{babel_reference_buckets[remote_string[:reference_bucket]].reference_module}-#{babel_reference_buckets[remote_string[:reference_bucket]].name}"
115
+
116
+ # add new string if it does not exist
117
+ local_string = CloudBabel::String.with_deleted.create_with({
118
+ bucket: babel_reference_buckets[remote_string[:reference_bucket]]
119
+ }).find_or_create_by({
120
+ label: remote_string[:label],
121
+ reference_module_bucket: remote_string_reference
122
+ })
123
+
124
+ # if status changed
125
+ if remote_string[:status] != local_string["status"]
126
+
127
+ remote_string[:last_update_status] = Time.now if remote_string[:last_update_status].blank?
128
+ local_string["last_update_status"] = Time.now if local_string["last_update_status"].blank?
129
+
130
+ # check if remote is newer than local
131
+ if (remote_string[:last_update_status] > local_string["last_update_status"])
132
+
133
+ # if so, update local translation with the incoming
134
+ local_string["status"] = remote_string[:status]
135
+ local_string["last_update_status"] = remote_string[:last_update_status]
136
+
137
+ end
138
+
139
+ end
140
+
141
+ # if context changed
142
+ if remote_string[:context] != local_string["context"]
143
+
144
+ remote_string[:last_update_context] = Time.now if remote_string[:last_update_context].blank?
145
+ local_string["last_update_context"] = Time.now if local_string["last_update_context"].blank?
146
+
147
+ # check if remote is newer than local
148
+ if (remote_string[:last_update_context] > local_string["last_update_context"])
149
+
150
+ # if so, update local translation with the incoming
151
+ local_string["context"] = remote_string[:context]
152
+ local_string["last_update_context"] = remote_string[:last_update_context]
153
+
154
+ end
155
+
156
+ end
157
+
158
+ # check if necessary to update any translation
159
+ # due babel can work as client and server at the same time, we have to synchronize labels for all supported languages
160
+ I18n.available_locales.each do |locale|
161
+
162
+ # parse the remote time for comparison, if no time use the current time
163
+ remote_time = Time.parse remote_string[:"last_update_#{locale}"] rescue Time.now.getutc
164
+
165
+ # parse the remote time for comparison, if no time use old time so we can update the string
166
+ local_time = Time.parse local_string["last_update_#{locale}"] rescue Time.parse("Jan 1900")
167
+
168
+ # if translation changed
169
+ if local_string[locale] != remote_string[:"#{locale}"]
170
+
171
+ # check if remote is newer than local
172
+ if (remote_time > local_time)
173
+
174
+ # if so, update local translation with the incoming
175
+ local_string[locale] = local_time
176
+ local_string["last_update_#{locale}"] = remote_time
177
+
178
+ end
179
+
180
+ end
181
+
182
+ end
183
+
184
+ local_string.save
185
+
186
+ end
187
+
188
+ return LC::Response.service(true) if double_way_sync == false
189
+
190
+ # · Collect modules, buckets and strings for syncronization
191
+
192
+ # get and parse modules
193
+ modules = CloudBabel::Module.all.map do |babel_module|
194
+ babel_module.as_json
195
+ end
196
+
197
+ # get and parse buckets
198
+ buckets = CloudBabel::Bucket.all.map do |babel_bucket|
199
+ babel_bucket.as_json
200
+ end
201
+
202
+ # get and parse strings including the deleted ones
203
+ strings = CloudBabel::String.with_deleted.all.map do |babel_string|
204
+ babel_string.as_json
205
+ end
206
+
207
+ # send latest translation to raven
208
+ response = Faraday.post(api_endpoint, ({ modules: modules, buckets: buckets, strings: strings }).to_json, "Content-Type" => "application/json")
209
+
210
+ LC::Response.service true
211
+
212
+ end
213
+
214
+ end
215
+ end
@@ -0,0 +1,80 @@
1
+ module LesliBabel
2
+ class StringService < Lesli::ApplicationLesliService
3
+
4
+ def list engines_id=nil, buckets_id=nil
5
+
6
+ # get strings with bucket and module information
7
+ strings = String
8
+ .joins("inner join lesli_babel_buckets on lesli_babel_buckets.id = lesli_babel_strings.bucket_id and lesli_babel_buckets.deleted_at is NULL")
9
+ .joins("inner join lesli_babel_modules on lesli_babel_modules.id = lesli_babel_buckets.module_id and lesli_babel_modules.deleted_at is NULL")
10
+ .where("lesli_babel_modules.id in (?)", ModuleService.new(current_user, query).list())
11
+
12
+ # filter by specific engines
13
+ if engines_id
14
+ strings = strings.where("lesli_babel_modules.id in (?)", engines_id)
15
+ end
16
+
17
+ # filter by specific engine buckets
18
+ if buckets_id
19
+ strings = strings.where("lesli_babel_buckets.id in (?)", buckets_id)
20
+ end
21
+
22
+ strings
23
+ end
24
+
25
+ def index params
26
+ strings = self.list.select(
27
+ :id,
28
+ :label,
29
+ :status,
30
+ :context,
31
+ Lesli.config.locales.keys,
32
+ "lesli_babel_modules.id as engine_id",
33
+ "lesli_babel_buckets.id as bucket_id",
34
+ "lesli_babel_buckets.name as bucket_name",
35
+ "lesli_babel_modules.name as engine_name",
36
+ "lesli_babel_modules.platform as platform",
37
+ "'' as path"
38
+ )
39
+
40
+ strings = strings
41
+ .page(query[:pagination][:page])
42
+ .per(query[:pagination][:perPage])
43
+ .order(:updated_at)
44
+ end
45
+
46
+ def stats
47
+
48
+ Rails.cache.fetch("babel/strings/stats", expires_in: 1.hour) do
49
+
50
+ # total translations registered in babel
51
+ total_strings = self.list.count
52
+
53
+ # total translations by language
54
+ total_strings_translations = []
55
+
56
+ #Rails.application.config.lesli.dig(:configuration, :locales_available).each do |locale|
57
+ Lesli.config.locales.each do |locale|
58
+ total_strings_translations.push({
59
+ code: locale[0],
60
+ name: locale[1],
61
+ total: self.list.where("#{locale[0]} is not null").where("#{locale[0]} != ''").count
62
+ })
63
+ end
64
+
65
+ # total translations that needs help
66
+ total_strings_waiting_for_help = self.list.where(:status => 1).count
67
+
68
+ # total translations that needs translation
69
+ total_strings_waiting_for_translation = self.list.where(:status => 2).count
70
+
71
+ {
72
+ total_strings: total_strings,
73
+ total_strings_translations: total_strings_translations,
74
+ total_strings_waiting_for_help: total_strings_waiting_for_help,
75
+ total_strings_waiting_for_translation: total_strings_waiting_for_translation
76
+ }
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,17 @@
1
+ <%= form_with(model: bucket, local: true) do |form| %>
2
+ <% if bucket.errors.any? %>
3
+ <div id="error_explanation">
4
+ <h2><%= pluralize(bucket.errors.count, "error") %> prohibited this bucket from being saved:</h2>
5
+
6
+ <ul>
7
+ <% bucket.errors.full_messages.each do |message| %>
8
+ <li><%= message %></li>
9
+ <% end %>
10
+ </ul>
11
+ </div>
12
+ <% end %>
13
+
14
+ <div class="actions">
15
+ <%= form.submit %>
16
+ </div>
17
+ <% end %>
@@ -0,0 +1,6 @@
1
+ <h1>Editing Bucket</h1>
2
+
3
+ <%= render 'form', bucket: @bucket %>
4
+
5
+ <%= link_to 'Show', @bucket %> |
6
+ <%= link_to 'Back', buckets_path %>
@@ -0,0 +1,25 @@
1
+ <p id="notice"><%= notice %></p>
2
+
3
+ <h1>Buckets</h1>
4
+
5
+ <table>
6
+ <thead>
7
+ <tr>
8
+ <th colspan="3"></th>
9
+ </tr>
10
+ </thead>
11
+
12
+ <tbody>
13
+ <% @buckets.each do |bucket| %>
14
+ <tr>
15
+ <td><%= link_to 'Show', bucket %></td>
16
+ <td><%= link_to 'Edit', edit_bucket_path(bucket) %></td>
17
+ <td><%= link_to 'Destroy', bucket, method: :delete, data: { confirm: 'Are you sure?' } %></td>
18
+ </tr>
19
+ <% end %>
20
+ </tbody>
21
+ </table>
22
+
23
+ <br>
24
+
25
+ <%= link_to 'New Bucket', new_bucket_path %>
@@ -0,0 +1,5 @@
1
+ <h1>New Bucket</h1>
2
+
3
+ <%= render 'form', bucket: @bucket %>
4
+
5
+ <%= link_to 'Back', buckets_path %>
@@ -0,0 +1,4 @@
1
+ <p id="notice"><%= notice %></p>
2
+
3
+ <%= link_to 'Edit', edit_bucket_path(@bucket) %> |
4
+ <%= link_to 'Back', buckets_path %>
@@ -0,0 +1,19 @@
1
+ <%
2
+ =begin
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
+ %>
@@ -0,0 +1,20 @@
1
+ <%
2
+ =begin
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
+ <router-view></router-view>
@@ -0,0 +1,20 @@
1
+ <%
2
+ =begin
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
+ <router-view></router-view>
@@ -0,0 +1,20 @@
1
+ <%
2
+ =begin
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
+ <router-view></router-view>