lit 0.2.6 → 0.3.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 (70) hide show
  1. checksums.yaml +5 -13
  2. data/README.md +93 -12
  3. data/Rakefile +1 -0
  4. data/app/assets/javascripts/lit/application.js +1 -2
  5. data/app/assets/javascripts/lit/{bootstrap.js.coffee → backend/bootstrap.js.coffee} +0 -0
  6. data/app/assets/javascripts/lit/{dashboard.js → backend/dashboard.js} +0 -0
  7. data/app/assets/javascripts/lit/{jquery-te-1.4.0.min.js → backend/jquery-te-1.4.0.min.js} +0 -0
  8. data/app/assets/javascripts/lit/{localizations.js.coffee → backend/localizations.js.coffee} +2 -0
  9. data/app/assets/javascripts/lit/backend/sources.js.coffee +24 -0
  10. data/app/assets/javascripts/lit/lit_frontend.js +103 -0
  11. data/app/assets/javascripts/lit/mousetrap.js +1044 -0
  12. data/app/assets/stylesheets/lit/application.css +7 -1
  13. data/app/assets/stylesheets/lit/{jquery-te-1.4.0.css.scss → backend/jquery-te-1.4.0.css.scss} +0 -0
  14. data/app/assets/stylesheets/lit/lit_frontend.css +86 -0
  15. data/app/controllers/lit/api/v1/base_controller.rb +1 -1
  16. data/app/controllers/lit/application_controller.rb +7 -3
  17. data/app/controllers/lit/concerns/request_info_store.rb +16 -0
  18. data/app/controllers/lit/concerns/request_keys_store.rb +16 -0
  19. data/app/controllers/lit/incomming_localizations_controller.rb +2 -2
  20. data/app/controllers/lit/locales_controller.rb +1 -1
  21. data/app/controllers/lit/localization_keys_controller.rb +22 -9
  22. data/app/controllers/lit/localizations_controller.rb +19 -6
  23. data/app/controllers/lit/sources_controller.rb +11 -1
  24. data/app/helpers/lit/frontend_helper.rb +71 -0
  25. data/app/helpers/lit/localization_keys_helper.rb +5 -0
  26. data/app/helpers/lit/sources_helper.rb +3 -0
  27. data/app/jobs/lit/synchronize_source_job.rb +11 -0
  28. data/app/models/lit/localization.rb +17 -10
  29. data/app/models/lit/localization_key.rb +6 -2
  30. data/app/models/lit/source.rb +4 -3
  31. data/app/views/layouts/lit/application.html.erb +6 -6
  32. data/app/views/lit/incomming_localizations/index.html.erb +22 -17
  33. data/app/views/lit/localization_keys/_localization_row.html.erb +1 -1
  34. data/app/views/lit/localization_keys/index.html.erb +27 -8
  35. data/app/views/lit/localizations/_form.html.erb +5 -5
  36. data/app/views/lit/localizations/_previous_versions_rows.html.erb +1 -1
  37. data/app/views/lit/localizations/edit.js.erb +2 -2
  38. data/app/views/lit/localizations/previous_versions.js.erb +1 -1
  39. data/app/views/lit/localizations/update.js.erb +2 -2
  40. data/config/routes.rb +12 -12
  41. data/db/migrate/20180101010101_lit_create_lit_locales.rb +16 -0
  42. data/db/migrate/20180101010102_lit_create_lit_localization_keys.rb +18 -0
  43. data/db/migrate/20180101010103_lit_create_lit_localizations.rb +24 -0
  44. data/db/migrate/20180101010104_lit_add_is_completed_and_is_starred_to_localization_keys.rb +17 -0
  45. data/db/migrate/20180101010105_lit_add_is_hidden_to_locales.rb +12 -0
  46. data/db/migrate/20180101010106_lit_create_lit_localization_versions.rb +20 -0
  47. data/db/migrate/20180101010107_lit_create_lit_sources.rb +19 -0
  48. data/db/migrate/20180101010108_lit_create_lit_incomming_localizations.rb +34 -0
  49. data/db/migrate/20180101010109_lit_add_sync_complete_to_lit_sources.rb +12 -0
  50. data/lib/generators/lit/install/templates/initializer.rb +17 -6
  51. data/lib/generators/lit/install_generator.rb +0 -7
  52. data/lib/lit.rb +15 -8
  53. data/lib/lit/adapters/hash_storage.rb +4 -0
  54. data/lib/lit/adapters/redis_storage.rb +9 -3
  55. data/lib/lit/cache.rb +126 -70
  56. data/lib/lit/engine.rb +20 -1
  57. data/lib/lit/i18n_backend.rb +66 -26
  58. data/lib/lit/version.rb +1 -1
  59. data/lib/tasks/lit_tasks.rake +21 -3
  60. metadata +67 -43
  61. data/app/assets/stylesheets/lit/dashboard.css +0 -4
  62. data/config/database.yml +0 -8
  63. data/db/migrate/20121103144612_create_lit_locales.rb +0 -9
  64. data/db/migrate/20121103174049_create_lit_localization_keys.rb +0 -10
  65. data/db/migrate/20121103182106_create_lit_localizations.rb +0 -15
  66. data/db/migrate/20121225112100_add_is_completed_and_is_starred_to_localization_keys.rb +0 -6
  67. data/db/migrate/20130511111904_add_is_hidden_to_locales.rb +0 -5
  68. data/db/migrate/20130921071304_create_lit_localization_versions.rb +0 -11
  69. data/db/migrate/20130923162141_create_lit_sources.rb +0 -12
  70. data/db/migrate/20130924151910_create_lit_incomming_localizations.rb +0 -21
@@ -8,7 +8,7 @@
8
8
  * You're free to add application-wide styles to this file and they'll appear at the top of the
9
9
  * compiled file, but it's generally better to create a new file per style scope.
10
10
  *
11
- *= require './jquery-te-1.4.0.css'
11
+ *= require './backend/jquery-te-1.4.0.css'
12
12
  *= require_self
13
13
  */
14
14
  .detail_wrapper{
@@ -51,3 +51,9 @@ padding: 5px 7px;
51
51
  .localization_row em{
52
52
  color: #bbb;
53
53
  }
54
+ .loading {
55
+ display: inline;
56
+ }
57
+ .loaded {
58
+ display: none;
59
+ }
@@ -0,0 +1,86 @@
1
+ .lit-key-generic {
2
+ }
3
+ .lit-key-highlight{
4
+ text-decoration: underline wavy red !important;
5
+ }
6
+ #lit_button_wrapper{
7
+ position: fixed;
8
+ bottom: 20px;
9
+ right: 20px;
10
+ z-index: 100;
11
+ background-color: red;
12
+ border-radius: 4px;
13
+ display: block;
14
+ padding: 5px;
15
+ cursor: pointer;
16
+ color: white;
17
+ }
18
+ #lit_button_wrapper.lit-highlight-enabled{
19
+ background-color: lightgreen;
20
+ }
21
+ #lit_textarea{
22
+ position: absolute;
23
+ padding: 0 0 1px 0;
24
+ margin: 0 0 0 0;
25
+ border: 0;
26
+ border-bottom: 1px solid red;
27
+
28
+ }
29
+ .lit-translations-info.collapsed {
30
+ position: fixed;
31
+ bottom: 60px;
32
+ right: 20px;
33
+ z-index: 100;
34
+ background-color: green;
35
+ border-radius: 4px;
36
+ display: block;
37
+ padding: 5px;
38
+ cursor: pointer;
39
+ color: white;
40
+ }
41
+ .lit-translations-info.expanded{
42
+ position: absolute;
43
+ display: block;
44
+ width: 80%;
45
+ overflow: auto;
46
+ height: 80%;
47
+ right: 10%;
48
+ left: 10%;
49
+ top: 10%;
50
+ background-color: rgba(240, 240, 240, 0.9);
51
+ border: 1px solid black;
52
+ z-index: 90;
53
+ }
54
+
55
+ .lit-translations-info.collapsed span.lit-open-button{
56
+ display: block;
57
+ }
58
+ .lit-translations-info.expanded span.lit-open-button{
59
+ display: none;
60
+ }
61
+ .lit-translations-info.collapsed span.lit-close-button{
62
+ display: none;
63
+ }
64
+ .lit-translations-info.expanded span.lit-close-button{
65
+ display: block;
66
+ position: fixed;
67
+ right: 10%;
68
+ border: 2px solid black;
69
+ font-size: 12pt;
70
+ font-weight: bold;
71
+ background-color: white;
72
+ padding: 10px 10px 5px;
73
+ }
74
+ .lit-translations-info.collapsed ul.lit-translations-list{
75
+ display: none;
76
+ }
77
+ .lit-translations-info.expanded ul.lit-translations-list{
78
+ }
79
+
80
+ .lit-translations-info.expanded ul.lit-translations-list li{
81
+ margin: 5px;
82
+ }
83
+
84
+ .lit-translations-info.expanded #lit_textarea{
85
+ padding: 2px;
86
+ }
@@ -4,7 +4,7 @@ module Lit
4
4
  class BaseController < ActionController::Base
5
5
  layout nil
6
6
  respond_to :json
7
- before_filter :authenticate_requests!
7
+ before_action :authenticate_requests!
8
8
 
9
9
  private
10
10
 
@@ -1,8 +1,12 @@
1
1
  module Lit
2
2
  class ApplicationController < ActionController::Base
3
- before_filter :authenticate
4
- before_filter :stop_hits_counter
5
- after_filter :restore_hits_counter
3
+ unless respond_to?(:before_action)
4
+ alias_method :before_action, :before_filter
5
+ alias_method :after_action, :after_filter
6
+ end
7
+ before_action :authenticate
8
+ before_action :stop_hits_counter
9
+ after_action :restore_hits_counter
6
10
 
7
11
  private
8
12
 
@@ -0,0 +1,16 @@
1
+ module Lit
2
+ module Concerns
3
+ module RequestInfoStore
4
+ extend ::ActiveSupport::Concern
5
+ included do
6
+ before_action :store_request_path
7
+ end
8
+
9
+ private
10
+
11
+ def store_request_path
12
+ Thread.current[:lit_current_request_path] = request&.path
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Lit
2
+ module Concerns
3
+ module RequestKeysStore
4
+ extend ::ActiveSupport::Concern
5
+ included do
6
+ before_action :init_request_keys
7
+ end
8
+
9
+ private
10
+
11
+ def init_request_keys
12
+ Thread.current[:lit_request_keys] = {}
13
+ end
14
+ end
15
+ end
16
+ end
@@ -2,10 +2,10 @@ require_dependency 'lit/application_controller'
2
2
 
3
3
  module Lit
4
4
  class IncommingLocalizationsController < ApplicationController
5
- before_filter :find_source
5
+ before_action :find_source
6
6
 
7
7
  def index
8
- @incomming_localizations = @source.incomming_localizations.all
8
+ @incomming_localizations = @source.incomming_localizations
9
9
  end
10
10
 
11
11
  def accept
@@ -3,7 +3,7 @@ require_dependency 'lit/application_controller'
3
3
  module Lit
4
4
  class LocalesController < ApplicationController
5
5
  def index
6
- @locales = Locale.ordered.all
6
+ @locales = Locale.ordered
7
7
 
8
8
  respond_to do |format|
9
9
  format.html # index.html.erb
@@ -1,15 +1,26 @@
1
1
  module Lit
2
2
  class LocalizationKeysController < ::Lit::ApplicationController
3
- before_filter :get_localization_scope, except: [:destroy]
3
+ before_action :get_localization_scope, except: [:destroy, :find_localization]
4
4
 
5
5
  def index
6
6
  get_localization_keys
7
7
  end
8
8
 
9
+ def find_localization
10
+ localization_key = Lit::LocalizationKey. \
11
+ find_by!(localization_key: params[:key])
12
+ locale = Lit::Locale.find_by!(locale: params[:locale])
13
+ localization = localization_key.localizations.find_by(locale_id: locale)
14
+ render json: {
15
+ path: localization_key_localization_path(localization_key, localization)
16
+ }
17
+ end
18
+
9
19
  def starred
10
20
  @scope = @scope.where(is_starred: true)
11
21
 
12
- if defined?(Kaminari) and @scope.respond_to?(Kaminari.config.page_method_name)
22
+ if defined?(Kaminari) && \
23
+ @scope.respond_to?(Kaminari.config.page_method_name)
13
24
  @scope = @scope.send(Kaminari.config.page_method_name, params[:page])
14
25
  end
15
26
  get_localization_keys
@@ -18,7 +29,7 @@ module Lit
18
29
 
19
30
  def star
20
31
  @localization_key = LocalizationKey.find params[:id].to_i
21
- @localization_key.is_starred = ! @localization_key.is_starred?
32
+ @localization_key.is_starred = !@localization_key.is_starred?
22
33
  @localization_key.save
23
34
  respond_to :js
24
35
  end
@@ -35,14 +46,18 @@ module Lit
35
46
  private
36
47
 
37
48
  def get_localization_scope
38
- @search_options = params.slice(*valid_keys)
49
+ @search_options = if params.respond_to?(:permit)
50
+ params.permit(*valid_keys)
51
+ else
52
+ params.slice(*valid_keys)
53
+ end
39
54
  @search_options[:include_completed] = '1' if @search_options.empty?
40
- @scope = LocalizationKey.uniq.preload(localizations: :locale).search(@search_options)
55
+ @scope = LocalizationKey.distinct.preload(localizations: :locale).search(@search_options)
41
56
  end
42
57
 
43
58
  def get_localization_keys
44
59
  key_parts = @search_options[:key_prefix].to_s.split('.').length
45
- @prefixes = @scope.reorder(nil).uniq.pluck(:localization_key).map { |lk| lk.split('.').shift(key_parts + 1).join('.') }.uniq.sort
60
+ @prefixes = @scope.reorder(nil).distinct.pluck(:localization_key).map { |lk| lk.split('.').shift(key_parts + 1).join('.') }.uniq.sort
46
61
  if @search_options[:key_prefix].present?
47
62
  parts = @search_options[:key_prefix].split('.')
48
63
  @parent_prefix = parts[0, parts.length - 1].join('.')
@@ -50,7 +65,7 @@ module Lit
50
65
  if defined?(Kaminari) and @scope.respond_to?(Kaminari.config.page_method_name)
51
66
  @localization_keys = @scope.send(Kaminari.config.page_method_name, params[:page])
52
67
  else
53
- @localization_keys = @scope.all
68
+ @localization_keys = @scope
54
69
  end
55
70
  end
56
71
 
@@ -88,7 +103,6 @@ module Lit
88
103
  ret
89
104
  end
90
105
  end
91
-
92
106
  helper_method :localization_for
93
107
 
94
108
  def has_versions?(localization)
@@ -98,7 +112,6 @@ module Lit
98
112
  end
99
113
  @_versions[localization.id].to_i > 0
100
114
  end
101
-
102
115
  helper_method :has_versions?
103
116
  end
104
117
  end
@@ -1,19 +1,31 @@
1
1
  module Lit
2
2
  class LocalizationsController < ::Lit::ApplicationController
3
- before_filter :find_localization_key
4
- before_filter :find_localization
3
+ before_action :find_localization_key
4
+ before_action :find_localization
5
+
6
+ def show
7
+ render json: { value: @localization.get_value }
8
+ end
5
9
 
6
10
  def edit
7
11
  @localization.translated_value = @localization.get_value
8
- respond_to :js
12
+ respond_to do |format|
13
+ format.js
14
+ end
9
15
  end
10
16
 
11
17
  def update
12
18
  if @localization.update_attributes(clear_params)
19
+ @localization.update_column :is_changed, true
13
20
  Lit.init.cache.update_cache @localization.full_key, @localization.get_value
14
21
  end
15
22
  @localization.reload
16
- respond_to :js
23
+ respond_to do |f|
24
+ f.js
25
+ f.json do
26
+ render json: { value: @localization.get_value }
27
+ end
28
+ end
17
29
  end
18
30
 
19
31
  def previous_versions
@@ -24,7 +36,8 @@ module Lit
24
36
  private
25
37
 
26
38
  def find_localization_key
27
- @localization_key = Lit::LocalizationKey.find(params[:localization_key_id])
39
+ @localization_key = Lit::LocalizationKey. \
40
+ find(params[:localization_key_id])
28
41
  end
29
42
 
30
43
  def find_localization
@@ -32,7 +45,7 @@ module Lit
32
45
  end
33
46
 
34
47
  def clear_params
35
- if defined?(::ActionController::StrongParameters)
48
+ if params.respond_to?(:permit)
36
49
  # allow translated_value to be an array
37
50
  if @localization.value.is_a?(Array)
38
51
  params.require(:localization).permit(:locale_id, translated_value: [])
@@ -20,7 +20,12 @@ module Lit
20
20
 
21
21
  def synchronize
22
22
  @source = Source.find(params[:id])
23
- @source.synchronize
23
+ @source.update_column(:sync_complete, false)
24
+ if defined?(ActiveJob)
25
+ SynchronizeSourceJob.perform_later(@source)
26
+ else
27
+ @source.synchronize
28
+ end
24
29
  redirect_to lit.source_incomming_localizations_path(@source)
25
30
  end
26
31
 
@@ -54,6 +59,11 @@ module Lit
54
59
  redirect_to sources_url
55
60
  end
56
61
 
62
+ def sync_complete
63
+ @source = Source.find(params[:id])
64
+ render json: { sync_complete: @source.sync_complete }
65
+ end
66
+
57
67
  private
58
68
 
59
69
  def clear_params
@@ -0,0 +1,71 @@
1
+ module Lit
2
+ module FrontendHelper
3
+ include ActionView::Helpers::TranslationHelper
4
+ module TranslationKeyWrapper
5
+ def translate(key, options = {})
6
+ options = options.with_indifferent_access
7
+ key = scope_key_by_partial(key)
8
+ ret = super(key, options)
9
+ if !options[:skip_lit] && lit_authorized?
10
+ ret = get_translateable_span(key, ret)
11
+ end
12
+ ret
13
+ end
14
+
15
+ def t(key, options = {})
16
+ translate(key, options)
17
+ end
18
+ end
19
+ prepend Lit::FrontendHelper::TranslationKeyWrapper
20
+
21
+ def javascript_lit_tag
22
+ javascript_include_tag 'lit/lit_frontend'
23
+ end
24
+
25
+ def stylesheet_lit_tag
26
+ stylesheet_link_tag 'lit/lit_frontend'
27
+ end
28
+
29
+ def lit_frontend_assets
30
+ return unless lit_authorized?
31
+ meta = content_tag :meta,
32
+ '',
33
+ value: lit.find_localization_localization_keys_path,
34
+ name: 'lit-url-base'
35
+ safe_join([javascript_lit_tag, stylesheet_lit_tag, meta])
36
+ end
37
+
38
+ def lit_translations_info
39
+ return if Thread.current[:lit_request_keys].nil?
40
+ return unless lit_authorized?
41
+ content_tag :div, class: 'lit-translations-info collapsed' do
42
+ concat content_tag :span, 'Show translations', class: 'lit-open-button'
43
+ concat content_tag :span, 'X', class: 'lit-close-button'
44
+ concat(content_tag(:ul, class: 'lit-translations-list') do
45
+ Lit.init.cache.request_keys.each do |k, v|
46
+ concat(content_tag(:li) do
47
+ concat content_tag :code, "#{k}:"
48
+ concat get_translateable_span(k, v, alternative_text: '[empty]')
49
+ end)
50
+ end
51
+ end)
52
+ end
53
+ end
54
+
55
+ def lit_authorized?
56
+ if Lit.authentication_verification.present?
57
+ send(Lit.authentication_verification)
58
+ else
59
+ true
60
+ end
61
+ end
62
+
63
+ def get_translateable_span(key, localization, alternative_text: nil)
64
+ content_tag :span,
65
+ class: 'lit-key-generic',
66
+ data: { key: key, locale: I18n.locale } do
67
+ localization.blank? ? alternative_text : localization
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,5 @@
1
+ module Lit
2
+ module LocalizationKeysHelper
3
+ include LocalizationsHelper
4
+ end
5
+ end
@@ -1,4 +1,7 @@
1
1
  module Lit
2
2
  module SourcesHelper
3
+ def source_loading_class(source)
4
+ source.sync_complete ? 'loaded' : 'loading'
5
+ end
3
6
  end
4
7
  end
@@ -0,0 +1,11 @@
1
+ module Lit
2
+ if defined?(::ActiveJob)
3
+ class SynchronizeSourceJob < ::ActiveJob::Base
4
+ queue_as :default
5
+
6
+ def perform(source)
7
+ source.synchronize
8
+ end
9
+ end
10
+ end
11
+ end