kakimasu 1.0.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/.coveralls.yml +1 -0
- data/.gitignore +12 -0
- data/.rspec +2 -0
- data/.rubocop.yml +31 -0
- data/.travis.yml +8 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +135 -0
- data/Rakefile +6 -0
- data/app/controllers/kakimasu/home_controller.rb +18 -0
- data/app/controllers/kakimasu/keys_controller.rb +89 -0
- data/app/controllers/kakimasu/translations_controller.rb +37 -0
- data/app/helpers/counting_helper.rb +11 -0
- data/app/helpers/formatting_helper.rb +6 -0
- data/app/helpers/grouping_helper.rb +11 -0
- data/app/helpers/pagination_helper.rb +15 -0
- data/app/helpers/search_key_helper.rb +66 -0
- data/app/helpers/search_translations_helper.rb +101 -0
- data/app/models/translation.rb +2 -0
- data/app/policies/translation_policy.rb +9 -0
- data/app/views/kakimasu/home/index.html.erb +35 -0
- data/app/views/kakimasu/keys/create.js.erb +1 -0
- data/app/views/kakimasu/keys/index.html.erb +183 -0
- data/app/views/kakimasu/shared/_navbar.html.erb +15 -0
- data/app/views/kakimasu/translations/create.js.erb +1 -0
- data/app/views/kakimasu/translations/index.html.erb +168 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/config/initializers/i18n.rb +58 -0
- data/config/initializers/i18n_backend.rb +5 -0
- data/config/locales/en.yml +34 -0
- data/config/routes.rb +10 -0
- data/kakimasu.gemspec +49 -0
- data/lib/generators/kakimasu/backup_generator.rb +101 -0
- data/lib/generators/kakimasu/policy_generator.rb +18 -0
- data/lib/generators/kakimasu/restore_backup_generator.rb +89 -0
- data/lib/generators/kakimasu/views_generator.rb +22 -0
- data/lib/kakimasu.rb +11 -0
- data/lib/kakimasu/engine.rb +3 -0
- data/lib/kakimasu/version.rb +3 -0
- data/vendor/assets/javascripts/components/activation_button.coffee +10 -0
- data/vendor/assets/javascripts/components/modal.coffee +48 -0
- data/vendor/assets/javascripts/components/translate.coffee +93 -0
- data/vendor/assets/javascripts/components/translation_key_table.coffee +5 -0
- data/vendor/assets/javascripts/components/translation_navigation.coffee +13 -0
- data/vendor/assets/javascripts/components/translation_panel_table.coffee +5 -0
- data/vendor/assets/javascripts/components/translation_percent_chart.coffee +39 -0
- data/vendor/assets/javascripts/components/translation_popover.coffee +90 -0
- data/vendor/assets/javascripts/jquery/jquery.circliful.min.js +1 -0
- data/vendor/assets/javascripts/kakimasu.coffee +18 -0
- data/vendor/assets/stylesheets/circliful.scss +38 -0
- data/vendor/assets/stylesheets/components/_homepage.scss +17 -0
- data/vendor/assets/stylesheets/components/_key_management.scss +53 -0
- data/vendor/assets/stylesheets/components/_navbar.scss +52 -0
- data/vendor/assets/stylesheets/components/_translate_modal.scss +36 -0
- data/vendor/assets/stylesheets/components/_translation_panel.scss +31 -0
- data/vendor/assets/stylesheets/components/_translation_popover.scss +31 -0
- data/vendor/assets/stylesheets/font-awesome/HELP-US-OUT.txt +7 -0
- data/vendor/assets/stylesheets/font-awesome/css/font-awesome.css +2337 -0
- data/vendor/assets/stylesheets/font-awesome/css/font-awesome.min.css +4 -0
- data/vendor/assets/stylesheets/font-awesome/fonts/FontAwesome.otf +0 -0
- data/vendor/assets/stylesheets/font-awesome/fonts/fontawesome-webfont.eot +0 -0
- data/vendor/assets/stylesheets/font-awesome/fonts/fontawesome-webfont.svg +2671 -0
- data/vendor/assets/stylesheets/font-awesome/fonts/fontawesome-webfont.ttf +0 -0
- data/vendor/assets/stylesheets/font-awesome/fonts/fontawesome-webfont.woff +0 -0
- data/vendor/assets/stylesheets/font-awesome/fonts/fontawesome-webfont.woff2 +0 -0
- data/vendor/assets/stylesheets/font-awesome/less/animated.less +34 -0
- data/vendor/assets/stylesheets/font-awesome/less/bordered-pulled.less +25 -0
- data/vendor/assets/stylesheets/font-awesome/less/core.less +12 -0
- data/vendor/assets/stylesheets/font-awesome/less/fixed-width.less +6 -0
- data/vendor/assets/stylesheets/font-awesome/less/font-awesome.less +18 -0
- data/vendor/assets/stylesheets/font-awesome/less/icons.less +789 -0
- data/vendor/assets/stylesheets/font-awesome/less/larger.less +13 -0
- data/vendor/assets/stylesheets/font-awesome/less/list.less +19 -0
- data/vendor/assets/stylesheets/font-awesome/less/mixins.less +60 -0
- data/vendor/assets/stylesheets/font-awesome/less/path.less +15 -0
- data/vendor/assets/stylesheets/font-awesome/less/rotated-flipped.less +20 -0
- data/vendor/assets/stylesheets/font-awesome/less/screen-reader.less +5 -0
- data/vendor/assets/stylesheets/font-awesome/less/stacked.less +20 -0
- data/vendor/assets/stylesheets/font-awesome/less/variables.less +800 -0
- data/vendor/assets/stylesheets/font-awesome/scss/_animated.scss +34 -0
- data/vendor/assets/stylesheets/font-awesome/scss/_bordered-pulled.scss +25 -0
- data/vendor/assets/stylesheets/font-awesome/scss/_core.scss +12 -0
- data/vendor/assets/stylesheets/font-awesome/scss/_fixed-width.scss +6 -0
- data/vendor/assets/stylesheets/font-awesome/scss/_icons.scss +789 -0
- data/vendor/assets/stylesheets/font-awesome/scss/_larger.scss +13 -0
- data/vendor/assets/stylesheets/font-awesome/scss/_list.scss +19 -0
- data/vendor/assets/stylesheets/font-awesome/scss/_mixins.scss +60 -0
- data/vendor/assets/stylesheets/font-awesome/scss/_path.scss +15 -0
- data/vendor/assets/stylesheets/font-awesome/scss/_rotated-flipped.scss +20 -0
- data/vendor/assets/stylesheets/font-awesome/scss/_screen-reader.scss +5 -0
- data/vendor/assets/stylesheets/font-awesome/scss/_stacked.scss +20 -0
- data/vendor/assets/stylesheets/font-awesome/scss/_variables.scss +800 -0
- data/vendor/assets/stylesheets/font-awesome/scss/font-awesome.scss +18 -0
- data/vendor/assets/stylesheets/kakimasu.scss +35 -0
- metadata +364 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module Kakimasu
|
|
2
|
+
module Generators
|
|
3
|
+
class PolicyGenerator < Rails::Generators::Base
|
|
4
|
+
puts "Generating Policy for you ..."
|
|
5
|
+
# Sets root for more compact file copying
|
|
6
|
+
source_root File.expand_path("../../../../app/policies", __FILE__)
|
|
7
|
+
|
|
8
|
+
# Copy policies for ability to edit them
|
|
9
|
+
def copy_policies
|
|
10
|
+
copy_file 'translation_policy.rb', 'app/policies/translations_policy.rb'
|
|
11
|
+
puts ''
|
|
12
|
+
puts '***********************************'
|
|
13
|
+
puts 'Policies was successfully generated!' # Success message
|
|
14
|
+
puts '***********************************'
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
module Kakimasu
|
|
2
|
+
module Generators
|
|
3
|
+
class RestoreBackupGenerator < Rails::Generators::Base
|
|
4
|
+
backup_file = '.kakimasu_backup.yml'
|
|
5
|
+
|
|
6
|
+
# Checks if there is backup file
|
|
7
|
+
unless File.file?(backup_file)
|
|
8
|
+
puts '**************************'
|
|
9
|
+
puts "Backup file can't be found"
|
|
10
|
+
puts '**************************'
|
|
11
|
+
|
|
12
|
+
else
|
|
13
|
+
# Reads content of backup file
|
|
14
|
+
backup_file_content = File.read(backup_file)
|
|
15
|
+
|
|
16
|
+
locale = nil # Used to store locale for a temporary time
|
|
17
|
+
key_parts = [] # Used to store parts of the 'lazy lookup' key, to at the end join them in one key
|
|
18
|
+
lazy_lookup = false # Determines if key is lazy lookup
|
|
19
|
+
|
|
20
|
+
# Read backup file by lines
|
|
21
|
+
backup_file_content.each_line do |line|
|
|
22
|
+
|
|
23
|
+
# Every line with translation starts with spaces
|
|
24
|
+
if line.start_with?(' ')
|
|
25
|
+
# Gets level of the key and gets translation
|
|
26
|
+
|
|
27
|
+
# Check if it is first level key
|
|
28
|
+
if line.match /^\s\s[\w]+[:]\s["][^"]+["]/
|
|
29
|
+
# Get translation key and translation from the line
|
|
30
|
+
translation_key = line.scan(/^\s\s([\w]+)[:]\s["][^"]+["]/).first.first
|
|
31
|
+
translation = line.scan(/^\s\s[\w]+[:]\s["]([^"]+)["]/).first.first
|
|
32
|
+
|
|
33
|
+
# empty 'lazy lookup' key parts array because this means that lazy lookup key is done even if there was no translation (That means it has no translation)
|
|
34
|
+
key_parts = []
|
|
35
|
+
lazy_lookup = false
|
|
36
|
+
|
|
37
|
+
# If its not first level translation, then it means that this is 'lazy lookup' translation
|
|
38
|
+
else
|
|
39
|
+
lazy_lookup = true
|
|
40
|
+
|
|
41
|
+
# If line has no translation, just key, then it is part of 'lazy lookup' key
|
|
42
|
+
if line.match /\w+[:]$/
|
|
43
|
+
key_parts.push line.scan(/(\w+)[:]$/).first.first # Gets 'lazy lookup' key part from the line and pushes it into array
|
|
44
|
+
|
|
45
|
+
# If key has translation then it is last part of 'lazy lookup' key
|
|
46
|
+
elsif line.match /\w+[:]\s["]([^"]+)["]/
|
|
47
|
+
# Gets 'lazy lookup' keys last part and gets translation
|
|
48
|
+
key_parts.push line.scan(/(\w+)[:]\s["][^"]+["]/).first.first
|
|
49
|
+
translation = line.scan(/\w+[:]\s["]([^"]+)["]/).first.first
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# lines with no spaces in start is just for locales or blank lines
|
|
54
|
+
else
|
|
55
|
+
# If line is not meant as blank line, then it's locale and function gets locale from it
|
|
56
|
+
locale = line.partition(':').first unless line.start_with?("\n")
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# If 'lazy lookup' key then save it as 'lazy lookup' key otherwise save it like not 'lazy lookup key'
|
|
60
|
+
if lazy_lookup && translation
|
|
61
|
+
# Form 'lazy lookup' key
|
|
62
|
+
translation_key = key_parts.join('.')
|
|
63
|
+
|
|
64
|
+
# Store translation
|
|
65
|
+
I18n.backend.store_translations(locale, {translation_key => translation}, escape: false)
|
|
66
|
+
|
|
67
|
+
# Set back variables
|
|
68
|
+
key_parts = []
|
|
69
|
+
translation = nil
|
|
70
|
+
translation_key = nil
|
|
71
|
+
|
|
72
|
+
elsif translation_key && translation
|
|
73
|
+
# Store translation
|
|
74
|
+
I18n.backend.store_translations(locale, {translation_key => translation}, escape: false)
|
|
75
|
+
|
|
76
|
+
# Set back variables
|
|
77
|
+
translation = nil
|
|
78
|
+
translation_key = nil
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Message about successfull translation restore from backup file
|
|
83
|
+
puts '***********************************'
|
|
84
|
+
puts 'Translations successfully restored!'
|
|
85
|
+
puts '***********************************'
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module Kakimasu
|
|
2
|
+
module Generators
|
|
3
|
+
class ViewsGenerator < Rails::Generators::Base
|
|
4
|
+
puts "Creating views for you ..."
|
|
5
|
+
# Sets root for more compact file copying
|
|
6
|
+
source_root File.expand_path("../../../../app/views/kakimasu", __FILE__)
|
|
7
|
+
|
|
8
|
+
# Copy all views to project folder for ability to edit them
|
|
9
|
+
def copy_views
|
|
10
|
+
copy_file "home/index.html.erb", "app/views/kakimasu/home/index.html.erb"
|
|
11
|
+
copy_file "keys/index.html.erb", "app/views/kakimasu/keys/index.html.erb"
|
|
12
|
+
copy_file "translations/index.html.erb", "app/views/kakimasu/translations/index.html.erb"
|
|
13
|
+
copy_file "translations/edit.html.erb", "app/views/kakimasu/translations/edit.html.erb"
|
|
14
|
+
copy_file "shared/_navbar.html.erb", "app/views/kakimasu/shared/_navbar.html.erb"
|
|
15
|
+
puts ''
|
|
16
|
+
puts '***********************************'
|
|
17
|
+
puts 'Views was successfully generated!' # Success message
|
|
18
|
+
puts '***********************************'
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
data/lib/kakimasu.rb
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
require 'kakimasu/version'
|
|
2
|
+
require 'kakimasu/engine'
|
|
3
|
+
|
|
4
|
+
module Kakimasu
|
|
5
|
+
# Turn of 'translation mode' mechanism
|
|
6
|
+
def set_show_translation_key
|
|
7
|
+
Thread.current[:show_translation_key] = nil
|
|
8
|
+
return unless current_user.try(:admin?)
|
|
9
|
+
Thread.current[:show_translation_key] = (params[:show_translation_key] == 'true').presence
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
class Kakimasu.TranslationModal
|
|
2
|
+
constructor: (el) ->
|
|
3
|
+
@$el = $(el)
|
|
4
|
+
@delegateEvents()
|
|
5
|
+
|
|
6
|
+
delegateEvents: ->
|
|
7
|
+
@$el.on 'click', '.translate-key-button', $.proxy(@fillModal, @)
|
|
8
|
+
|
|
9
|
+
fillModal: (e) ->
|
|
10
|
+
$chosenKey = $(e.currentTarget)
|
|
11
|
+
$('#translation-modal-form #key').val($chosenKey.data('key'))
|
|
12
|
+
$('#translation-modal-form #path').val($chosenKey.data('path'))
|
|
13
|
+
|
|
14
|
+
$('.translation-key').text $chosenKey.data('key')
|
|
15
|
+
$('.translation-key-path').text "( #{$chosenKey.data('path')} )"
|
|
16
|
+
|
|
17
|
+
html = ''
|
|
18
|
+
html += '<p id="lazy-lookup-checkbox-tag">'
|
|
19
|
+
html += '<label for="Unique">Unique</label>'
|
|
20
|
+
html += '<input type="checkbox" name="lazy_lookup" id="lazy_lookup" value="1"'
|
|
21
|
+
if $chosenKey.data('unique')
|
|
22
|
+
html += 'checked="checked"'
|
|
23
|
+
html += '>'
|
|
24
|
+
html += '</p>'
|
|
25
|
+
$('#lazy-lookup-checkbox-tag').remove()
|
|
26
|
+
$('#translation-modal-form #lazy-lookup-checkbox').append html
|
|
27
|
+
|
|
28
|
+
translations = $chosenKey.data('translations')
|
|
29
|
+
locales = $chosenKey.data('locales')
|
|
30
|
+
|
|
31
|
+
for l, index in locales
|
|
32
|
+
translation = translations[index]
|
|
33
|
+
translation = translation.replace /\u0026#39;/g, "'"
|
|
34
|
+
$("#translation-modal-form ##{l}").val('')
|
|
35
|
+
if translation
|
|
36
|
+
unless translation.match /<span.*<\/span>/
|
|
37
|
+
$("#translation-modal-form ##{l}").val(translation)
|
|
38
|
+
$("#translation-modal-form ##{l}").attr('name', l)
|
|
39
|
+
$("#translation-modal-form ##{l}").attr('value', translation)
|
|
40
|
+
else
|
|
41
|
+
if translation.match /<span class='(translation-with-key).*<\/span>/
|
|
42
|
+
match = /<span.*>(.*)<\/span>/i.exec translation
|
|
43
|
+
$("#translation-modal-form ##{l}").val(match[1])
|
|
44
|
+
$("#translation-modal-form ##{l}").attr('name', l)
|
|
45
|
+
$("#translation-modal-form ##{l}").attr('value', match[1])
|
|
46
|
+
|
|
47
|
+
# Closes collapse element if it is open
|
|
48
|
+
$('.collapse').removeClass('in')
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
$(document).on 'click', '.suggested-translation-link', () ->
|
|
2
|
+
form = $(this).parent().parent().parent().parent() # Get form
|
|
3
|
+
|
|
4
|
+
# Get target language, and also check if there is textare or just input
|
|
5
|
+
if $(this).parent().parent().children('.translation-input').children('input').attr('name')
|
|
6
|
+
targetLanguage = $(this).parent().parent().children('.translation-input').children('input').attr('name')
|
|
7
|
+
else
|
|
8
|
+
targetLanguage = $(this).parent().parent().children('.translation-input').children('textarea').attr('name')
|
|
9
|
+
|
|
10
|
+
numberOfLanguages = form.children('.form-group').length # Get number of all languages
|
|
11
|
+
|
|
12
|
+
# Will be used if there is no translation for the key in other languages but there is translation for the key in this language
|
|
13
|
+
hasTranslation = false
|
|
14
|
+
|
|
15
|
+
# Get source language and translatable string (first language with translation which is not target language)
|
|
16
|
+
for i in [0...numberOfLanguages]
|
|
17
|
+
formGroup = form.children('.form-group').eq(i)
|
|
18
|
+
# Determines if there ir textarea or input field
|
|
19
|
+
if formGroup.children().eq(0).children('.translation-input').children('textarea').val()
|
|
20
|
+
value = formGroup.children().eq(0).children('.translation-input').children('textarea').val()
|
|
21
|
+
language = formGroup.children().eq(0).children('.translation-input').children('textarea').attr('name')
|
|
22
|
+
else
|
|
23
|
+
value = formGroup.children().eq(0).children('.translation-input').children('input').val()
|
|
24
|
+
language = formGroup.children().eq(0).children('.translation-input').children('input').attr('name')
|
|
25
|
+
|
|
26
|
+
# If there is translation for key in language that is not target language then it will be translatable string
|
|
27
|
+
if value && language != targetLanguage
|
|
28
|
+
sourceLanguage = language
|
|
29
|
+
translatableString = value
|
|
30
|
+
break
|
|
31
|
+
# In case if there is no other language with translation and this language has translation then this will be displayed translation
|
|
32
|
+
if value && language == targetLanguage
|
|
33
|
+
hasTranslation = true
|
|
34
|
+
result = value
|
|
35
|
+
|
|
36
|
+
# Alert user if there is nothing to get translation from
|
|
37
|
+
alert 'There is no word to translate. Please fill at least one translation.' unless translatableString || hasTranslation
|
|
38
|
+
|
|
39
|
+
# Check for internet connection, if there is no connection then alert user
|
|
40
|
+
unless navigator.onLine
|
|
41
|
+
alert 'Unable to connect google translate service. Please make sure that you are connected to the internet!'
|
|
42
|
+
else
|
|
43
|
+
if translatableString
|
|
44
|
+
# Regular expression for searching punctuation marks
|
|
45
|
+
regex = /[^\.!\?]+[\.!\?]+/g
|
|
46
|
+
|
|
47
|
+
# If translatable string includes many sentences then every sentence should be translated independently
|
|
48
|
+
if regex.test(translatableString)
|
|
49
|
+
sentences = translatableString.match( regex )
|
|
50
|
+
|
|
51
|
+
# Array for translation storage
|
|
52
|
+
translation = []
|
|
53
|
+
|
|
54
|
+
# Translate every sentence independently
|
|
55
|
+
for sentence in sentences
|
|
56
|
+
# Google translate API url
|
|
57
|
+
url = "https://translate.googleapis.com/translate_a/single?client=gtx"
|
|
58
|
+
url += "&sl=" + sourceLanguage
|
|
59
|
+
url += "&tl=" + targetLanguage
|
|
60
|
+
url += "&dt=t&q=" + encodeURI(sentence)
|
|
61
|
+
|
|
62
|
+
# HTTP GET request for translation
|
|
63
|
+
xmlHttp = new XMLHttpRequest()
|
|
64
|
+
xmlHttp.open( "GET", url, false )
|
|
65
|
+
xmlHttp.send( null )
|
|
66
|
+
|
|
67
|
+
# Parse API response to JSON
|
|
68
|
+
response = JSON.parse(xmlHttp.responseText)
|
|
69
|
+
|
|
70
|
+
# Get suggested translation
|
|
71
|
+
translation.push response[0][0][0]
|
|
72
|
+
|
|
73
|
+
result = translation.join(' ')
|
|
74
|
+
|
|
75
|
+
# If translatable string is just one sentence then it can be translated directly
|
|
76
|
+
else
|
|
77
|
+
# Google translate API url
|
|
78
|
+
url = "https://translate.googleapis.com/translate_a/single?client=gtx"
|
|
79
|
+
url += "&sl=" + sourceLanguage
|
|
80
|
+
url += "&tl=" + targetLanguage
|
|
81
|
+
url += "&dt=t&q=" + encodeURI(translatableString)
|
|
82
|
+
|
|
83
|
+
# HTTP GET request for translation
|
|
84
|
+
xmlHttp = new XMLHttpRequest()
|
|
85
|
+
xmlHttp.open( "GET", url, false )
|
|
86
|
+
xmlHttp.send( null )
|
|
87
|
+
|
|
88
|
+
# Get translation
|
|
89
|
+
response = JSON.parse(xmlHttp.responseText)
|
|
90
|
+
result = response[0][0][0]
|
|
91
|
+
|
|
92
|
+
# Show suggested translation to user
|
|
93
|
+
$(this).children('.suggested-translation').children('p').text result
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
class Kakimasu.TranslationNavigation
|
|
2
|
+
constructor: (el) ->
|
|
3
|
+
@$el = $(el)
|
|
4
|
+
@delegateEvents()
|
|
5
|
+
|
|
6
|
+
delegateEvents: ->
|
|
7
|
+
@$el.on 'click', 'li', $.proxy(@changeActiveListItem, @)
|
|
8
|
+
|
|
9
|
+
changeActiveListItem: (e) ->
|
|
10
|
+
$chosenItem = $(e.currentTarget)
|
|
11
|
+
|
|
12
|
+
$('.kakimasu-navigation .active').removeClass('active')
|
|
13
|
+
$chosenItem.addClass('active')
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
class Kakimasu.TranslationPercentChart
|
|
2
|
+
constructor: (el) ->
|
|
3
|
+
# Get translation percentage from the view
|
|
4
|
+
percentage = $('.translation-percentage').data('value')
|
|
5
|
+
|
|
6
|
+
# Set chart and text color
|
|
7
|
+
if percentage <= 25
|
|
8
|
+
chartColor = '#8B0000'
|
|
9
|
+
textColor = '#4D0000'
|
|
10
|
+
else if percentage <= 50 && percentage > 25
|
|
11
|
+
chartColor = '#FF0000'
|
|
12
|
+
textColor = '#B30000'
|
|
13
|
+
else if percentage <=75 && percentage > 50
|
|
14
|
+
chartColor = '#FFA500'
|
|
15
|
+
textColor = '#B37400'
|
|
16
|
+
else if percentage <= 90 && percentage > 75
|
|
17
|
+
chartColor = '#808000'
|
|
18
|
+
textColor = '#808000'
|
|
19
|
+
else if percentage <= 99 && percentage > 90
|
|
20
|
+
chartColor = '#6B8E23'
|
|
21
|
+
textColor = '#3D5214'
|
|
22
|
+
else
|
|
23
|
+
chartColor = '#008000'
|
|
24
|
+
textColor = '#003300'
|
|
25
|
+
|
|
26
|
+
# translation percentage circle diagram
|
|
27
|
+
$('#translation-percentage-circle').circliful
|
|
28
|
+
animation: 1
|
|
29
|
+
animationStep: 2
|
|
30
|
+
start: 2
|
|
31
|
+
showPercent: 1
|
|
32
|
+
percent: percentage
|
|
33
|
+
backgroundColor: '#666666'
|
|
34
|
+
foregroundColor: chartColor
|
|
35
|
+
fontColor: textColor
|
|
36
|
+
multiPercentage: 1
|
|
37
|
+
foregroundBorderWidth: 15
|
|
38
|
+
backgroundBorderWidth: 1
|
|
39
|
+
percentageY: 105
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
class Kakimasu.TranslationPopover
|
|
2
|
+
constructor: (el) ->
|
|
3
|
+
@$el = $(el)
|
|
4
|
+
@delegateEvents()
|
|
5
|
+
|
|
6
|
+
delegateEvents: ->
|
|
7
|
+
@$el.on 'mouseenter', $.proxy(@showPopover, @)
|
|
8
|
+
|
|
9
|
+
showPopover: (e) ->
|
|
10
|
+
$translation = $(e.currentTarget)
|
|
11
|
+
|
|
12
|
+
token = $('meta[name="csrf-token"]').attr('content')
|
|
13
|
+
url_params = window.location.search
|
|
14
|
+
key = $translation.data('content')
|
|
15
|
+
translations = $translation.data('translations')
|
|
16
|
+
|
|
17
|
+
#determine available locales
|
|
18
|
+
locales = $translation.data('locales')
|
|
19
|
+
locales = locales.split /\W+/
|
|
20
|
+
locales.shift()
|
|
21
|
+
locales.pop()
|
|
22
|
+
|
|
23
|
+
html = '<div class="popover translation-popover">'
|
|
24
|
+
html += '<div class="close">'
|
|
25
|
+
html += '<p>×</p>'
|
|
26
|
+
html += '</div>'
|
|
27
|
+
html += '<form action="/kakimasu/translations'
|
|
28
|
+
html += url_params
|
|
29
|
+
html += '" data-remote="true" method="post">'
|
|
30
|
+
html += '<input type="hidden" name="authenticity_token" '
|
|
31
|
+
html += 'value='
|
|
32
|
+
html += token
|
|
33
|
+
html += '>'
|
|
34
|
+
html += '<input type="hidden" name="key" id="translation-key" value='
|
|
35
|
+
html += key
|
|
36
|
+
html += '>'
|
|
37
|
+
html += '<div class="translation-key">'
|
|
38
|
+
html += key
|
|
39
|
+
html += '</div>'
|
|
40
|
+
for l, index in locales
|
|
41
|
+
html += '<div class="form-group">'
|
|
42
|
+
html += '<div class="row">'
|
|
43
|
+
html += '<div class="col-xs-2">'
|
|
44
|
+
html += "<label for='locale'>#{l}</label>"
|
|
45
|
+
html += '</div>'
|
|
46
|
+
html += '<div class="col-xs-10 translation-input">'
|
|
47
|
+
field_value = translations[index].replace /"/g, '"'
|
|
48
|
+
field_value = '"' + field_value + '"'
|
|
49
|
+
html += "<input class='form-control' type='text' name='#{l}' id='value' value=#{field_value} >"
|
|
50
|
+
html += '</div>'
|
|
51
|
+
html += '<div class="col-xs-10 col-xs-offset-2">'
|
|
52
|
+
html += "<div class='suggested-translation-link'>"
|
|
53
|
+
html += "<a href='#popover-translation-#{index}' data-toggle='collapse'>"
|
|
54
|
+
html += 'suggested translations'
|
|
55
|
+
html += '</a>'
|
|
56
|
+
html += "<div id='popover-translation-#{index}' class='collapse suggested-translation'>"
|
|
57
|
+
html += '<p></p>'
|
|
58
|
+
html += '</div>'
|
|
59
|
+
html += '</div>'
|
|
60
|
+
html += '</div>'
|
|
61
|
+
html += '</div>'
|
|
62
|
+
html += '</div>'
|
|
63
|
+
if $translation.data('unique')
|
|
64
|
+
html += '<p>'
|
|
65
|
+
html += '<label for="Unique">Unique</label>'
|
|
66
|
+
html += '<input type="checkbox" name="lazy_lookup" id="lazy_lookup" value="1"'
|
|
67
|
+
html += 'checked="checked"'
|
|
68
|
+
html += 'disabled'
|
|
69
|
+
html += '>'
|
|
70
|
+
html += '</p>'
|
|
71
|
+
html += '<p class="text-right">'
|
|
72
|
+
html += '<input type="submit" name="commit" value="Save" class="btn btn-primary">'
|
|
73
|
+
html += '</p>'
|
|
74
|
+
html += '</form>'
|
|
75
|
+
html += '</div>'
|
|
76
|
+
|
|
77
|
+
$translation.popover
|
|
78
|
+
container: 'body'
|
|
79
|
+
template: html
|
|
80
|
+
|
|
81
|
+
$('.popover').remove()
|
|
82
|
+
$('.translation-with-key').css 'background-color', '#FFCCCC'
|
|
83
|
+
$('.translation_missing').css 'background-color', '#FF6666'
|
|
84
|
+
$translation.popover('show')
|
|
85
|
+
$translation.css 'background-color', '#990000'
|
|
86
|
+
|
|
87
|
+
$('.close').on 'click', ->
|
|
88
|
+
$(this).closest('.popover').hide()
|
|
89
|
+
$('.translation-with-key').css 'background-color', '#FFCCCC'
|
|
90
|
+
$('.translation_missing').css 'background-color', '#FF6666'
|