decidim-term_customizer 0.16.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE-AGPLv3.txt +661 -0
  3. data/README.md +180 -0
  4. data/Rakefile +48 -0
  5. data/app/assets/config/translation_sets_admin_manifest.js +2 -0
  6. data/app/assets/javascripts/decidim/term_customizer/admin/constraint_fields.js.es6 +45 -0
  7. data/app/assets/javascripts/decidim/term_customizer/admin/multifield/component.js.es6 +103 -0
  8. data/app/assets/javascripts/decidim/term_customizer/admin/multifield.js.es6 +5 -0
  9. data/app/assets/javascripts/decidim/term_customizer/admin/translation_sets_admin.js.es6 +19 -0
  10. data/app/assets/javascripts/decidim/term_customizer/admin/translations_admin.js.es6 +72 -0
  11. data/app/commands/decidim/term_customizer/admin/create_translation.rb +53 -0
  12. data/app/commands/decidim/term_customizer/admin/create_translation_set.rb +68 -0
  13. data/app/commands/decidim/term_customizer/admin/import_translation_keys.rb +59 -0
  14. data/app/commands/decidim/term_customizer/admin/update_translation.rb +65 -0
  15. data/app/commands/decidim/term_customizer/admin/update_translation_set.rb +61 -0
  16. data/app/controllers/decidim/term_customizer/admin/add_translations_controller.rb +72 -0
  17. data/app/controllers/decidim/term_customizer/admin/application_controller.rb +15 -0
  18. data/app/controllers/decidim/term_customizer/admin/translation_sets_controller.rb +107 -0
  19. data/app/controllers/decidim/term_customizer/admin/translations_controller.rb +102 -0
  20. data/app/forms/decidim/term_customizer/admin/translation_form.rb +39 -0
  21. data/app/forms/decidim/term_customizer/admin/translation_key_import_form.rb +15 -0
  22. data/app/forms/decidim/term_customizer/admin/translation_set_constraint_form.rb +58 -0
  23. data/app/forms/decidim/term_customizer/admin/translation_set_form.rb +18 -0
  24. data/app/forms/decidim/term_customizer/admin/translation_set_subject_component_form.rb +12 -0
  25. data/app/forms/decidim/term_customizer/admin/translation_set_subject_form.rb +61 -0
  26. data/app/helpers/decidim/term_customizer/admin/application_helper.rb +13 -0
  27. data/app/models/decidim/term_customizer/application_record.rb +10 -0
  28. data/app/models/decidim/term_customizer/constraint.rb +36 -0
  29. data/app/models/decidim/term_customizer/translation.rb +23 -0
  30. data/app/models/decidim/term_customizer/translation_set.rb +19 -0
  31. data/app/permissions/decidim/term_customizer/admin/permissions.rb +66 -0
  32. data/app/queries/decidim/term_customizer/organization_translation_sets.rb +37 -0
  33. data/app/queries/decidim/term_customizer/set_translations.rb +21 -0
  34. data/app/views/decidim/term_customizer/admin/add_translations/index.html.erb +59 -0
  35. data/app/views/decidim/term_customizer/admin/translation_sets/_constraint_fields.html.erb +58 -0
  36. data/app/views/decidim/term_customizer/admin/translation_sets/_form.html.erb +29 -0
  37. data/app/views/decidim/term_customizer/admin/translation_sets/edit.html.erb +9 -0
  38. data/app/views/decidim/term_customizer/admin/translation_sets/index.html.erb +44 -0
  39. data/app/views/decidim/term_customizer/admin/translation_sets/new.html.erb +9 -0
  40. data/app/views/decidim/term_customizer/admin/translations/_form.html.erb +15 -0
  41. data/app/views/decidim/term_customizer/admin/translations/edit.html.erb +7 -0
  42. data/app/views/decidim/term_customizer/admin/translations/index.html.erb +52 -0
  43. data/app/views/decidim/term_customizer/admin/translations/new.html.erb +7 -0
  44. data/config/locales/en.yml +65 -0
  45. data/config/locales/fi.yml +65 -0
  46. data/config/locales/sv.yml +65 -0
  47. data/lib/decidim/term_customizer/admin.rb +10 -0
  48. data/lib/decidim/term_customizer/admin_engine.rb +46 -0
  49. data/lib/decidim/term_customizer/engine.rb +35 -0
  50. data/lib/decidim/term_customizer/i18n_backend.rb +82 -0
  51. data/lib/decidim/term_customizer/resolver.rb +108 -0
  52. data/lib/decidim/term_customizer/test/factories.rb +43 -0
  53. data/lib/decidim/term_customizer/translation_directory.rb +50 -0
  54. data/lib/decidim/term_customizer/translation_store.rb +67 -0
  55. data/lib/decidim/term_customizer/version.rb +8 -0
  56. data/lib/decidim/term_customizer.rb +21 -0
  57. metadata +170 -0
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module TermCustomizer
5
+ module Admin
6
+ # A command with all the business logic when creating a new translation
7
+ # set in the system.
8
+ class CreateTranslation < Rectify::Command
9
+ # Public: Initializes the command.
10
+ #
11
+ # form - A form object with the params.
12
+ def initialize(form)
13
+ @form = form
14
+ end
15
+
16
+ # Executes the command. Broadcasts these events:
17
+ #
18
+ # - :ok when everything is valid.
19
+ # - :invalid if the form wasn't valid and we couldn't proceed.
20
+ #
21
+ # Returns nothing.
22
+ def call
23
+ return broadcast(:invalid) if form.invalid?
24
+
25
+ transaction do
26
+ @translations = create_translations
27
+ end
28
+
29
+ if @translations.length.positive?
30
+ broadcast(:ok, @translations)
31
+ else
32
+ broadcast(:invalid)
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ attr_reader :form
39
+
40
+ def create_translations
41
+ form.value.map do |locale, value|
42
+ TermCustomizer::Translation.create!(
43
+ translation_set: form.translation_set,
44
+ key: form.key,
45
+ value: value,
46
+ locale: locale
47
+ )
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module TermCustomizer
5
+ module Admin
6
+ # A command with all the business logic when creating a new translation
7
+ # set in the system.
8
+ class CreateTranslationSet < Rectify::Command
9
+ # Public: Initializes the command.
10
+ #
11
+ # form - A form object with the params.
12
+ def initialize(form)
13
+ @form = form
14
+ end
15
+
16
+ # Executes the command. Broadcasts these events:
17
+ #
18
+ # - :ok when everything is valid.
19
+ # - :invalid if the form wasn't valid and we couldn't proceed.
20
+ #
21
+ # Returns nothing.
22
+ def call
23
+ return broadcast(:invalid) if form.invalid?
24
+
25
+ transaction do
26
+ @set = create_translation_set!
27
+ end
28
+
29
+ if @set.persisted?
30
+ broadcast(:ok, @set)
31
+ else
32
+ broadcast(:invalid)
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ attr_reader :form
39
+
40
+ def create_translation_set!
41
+ translation_set = TermCustomizer::TranslationSet.create!(
42
+ name: form.name
43
+ )
44
+
45
+ form.constraints.each do |c|
46
+ next if c.deleted
47
+
48
+ attrs = { organization: form.current_organization }
49
+ if c.subject
50
+ attrs[:subject] = c.subject
51
+ else
52
+ attrs[:subject_type] = c.subject_type
53
+ end
54
+
55
+ translation_set.constraints.create!(attrs)
56
+ end
57
+
58
+ if translation_set.constraints.count < 1
59
+ # Make sure that the organization constraint at least exists always
60
+ translation_set.constraints.create!(organization: form.current_organization)
61
+ end
62
+
63
+ translation_set
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module TermCustomizer
5
+ module Admin
6
+ # A command with all the business logic when creating new translations
7
+ # from the keys submitted through the form.
8
+ class ImportTranslationKeys < Rectify::Command
9
+ # Public: Initializes the command.
10
+ #
11
+ # form - A form object with the params.
12
+ def initialize(form)
13
+ @form = form
14
+ end
15
+
16
+ # Executes the command. Broadcasts these events:
17
+ #
18
+ # - :ok when everything is valid.
19
+ # - :invalid if the form wasn't valid and we couldn't proceed.
20
+ #
21
+ # Returns nothing.
22
+ def call
23
+ return broadcast(:invalid) if form.invalid?
24
+
25
+ transaction do
26
+ @translations = create_translations
27
+ end
28
+
29
+ if @translations.length.positive?
30
+ broadcast(:ok, @translations)
31
+ else
32
+ broadcast(:invalid)
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ attr_reader :form
39
+
40
+ def create_translations
41
+ form.keys.each do |key|
42
+ form.current_organization.available_locales.each do |locale|
43
+ attrs = {
44
+ translation_set: form.translation_set,
45
+ key: key,
46
+ locale: locale
47
+ }
48
+ next unless TermCustomizer::Translation.find_by(attrs).nil?
49
+
50
+ TermCustomizer::Translation.create!(
51
+ attrs.merge(value: I18n.t(key, locale: locale, default: ""))
52
+ )
53
+ end
54
+ end.flatten
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module TermCustomizer
5
+ module Admin
6
+ # This command is executed when the user changes a translation from the
7
+ # admin panel.
8
+ class UpdateTranslation < Rectify::Command
9
+ # Public: Initializes the command.
10
+ #
11
+ # form - A form object with the params.
12
+ # translation - The current instance of the translation to be updated.
13
+ def initialize(form, translation)
14
+ @form = form
15
+ @translation = translation
16
+ end
17
+
18
+ # Executes the command. Broadcasts these events:
19
+ #
20
+ # - :ok when everything is valid.
21
+ # - :invalid if the form wasn't valid and we couldn't proceed.
22
+ #
23
+ # Returns nothing.
24
+ def call
25
+ return broadcast(:invalid) if form.invalid?
26
+
27
+ transaction do
28
+ update_translations!
29
+ end
30
+
31
+ broadcast(:ok, translation)
32
+ end
33
+
34
+ private
35
+
36
+ attr_reader :form, :translation
37
+
38
+ def update_translations!
39
+ form.value.each do |locale, value|
40
+ l_translation = TermCustomizer::Translation.find_by(
41
+ translation_set: translation.translation_set,
42
+ key: translation.key,
43
+ locale: locale
44
+ )
45
+
46
+ if l_translation
47
+ l_translation.update!(
48
+ key: form.key,
49
+ value: value,
50
+ locale: locale
51
+ )
52
+ else
53
+ TermCustomizer::Translation.create!(
54
+ translation_set: translation.translation_set,
55
+ key: form.key,
56
+ value: value,
57
+ locale: locale
58
+ )
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module TermCustomizer
5
+ module Admin
6
+ # This command is executed when the user changes a translation set from
7
+ # the admin panel.
8
+ class UpdateTranslationSet < Rectify::Command
9
+ # Initializes a UpdateTranslationSet Command.
10
+ #
11
+ # form - The form from which to get the data.
12
+ # set - The current instance of the translation set to be updated.
13
+ def initialize(form, set)
14
+ @form = form
15
+ @set = set
16
+ end
17
+
18
+ # Updates the blog if valid.
19
+ #
20
+ # Broadcasts :ok if successful, :invalid otherwise.
21
+ def call
22
+ return broadcast(:invalid) if form.invalid?
23
+
24
+ transaction do
25
+ update_translation_set!
26
+ end
27
+
28
+ broadcast(:ok, set)
29
+ end
30
+
31
+ private
32
+
33
+ attr_reader :form, :set
34
+
35
+ def update_translation_set!
36
+ set.update!(name: form.name)
37
+
38
+ # Update the constraints
39
+ set.constraints.destroy_all
40
+ form.constraints.each do |c|
41
+ next if c.deleted
42
+
43
+ attrs = { organization: form.current_organization }
44
+ if c.subject
45
+ attrs[:subject] = c.subject
46
+ else
47
+ attrs[:subject_type] = c.subject_type
48
+ end
49
+
50
+ set.constraints.create!(attrs)
51
+ end
52
+
53
+ if set.constraints.count < 1
54
+ # Make sure that the organization constraint at least exists always
55
+ set.constraints.create!(organization: form.current_organization)
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module TermCustomizer
5
+ module Admin
6
+ class AddTranslationsController < TermCustomizer::Admin::ApplicationController
7
+ helper_method :set
8
+
9
+ def index
10
+ enforce_permission_to :read, :translation
11
+
12
+ @form = form(TranslationKeyImportForm).from_model(Translation.new)
13
+ end
14
+
15
+ def create
16
+ enforce_permission_to :create, :translation
17
+ @form = form(TranslationKeyImportForm).from_params(
18
+ params,
19
+ translation_set: set
20
+ )
21
+
22
+ ImportTranslationKeys.call(@form) do
23
+ on(:ok) do
24
+ flash[:notice] = I18n.t("translations.create.success", scope: "decidim.term_customizer.admin")
25
+ redirect_to translation_set_translations_path(set)
26
+ end
27
+
28
+ on(:invalid) do
29
+ flash.now[:alert] = I18n.t("translations.create.error", scope: "decidim.term_customizer.admin")
30
+ render action: "index"
31
+ end
32
+ end
33
+ end
34
+
35
+ def search
36
+ enforce_permission_to :read, :translation
37
+ return render json: [] unless params.has_key?(:term)
38
+
39
+ directory = TranslationDirectory.new(current_locale)
40
+ translations = directory.translations_search(params[:term])
41
+ translations.reject! { |k| reject_keys.include?(k) }
42
+
43
+ render json: translations.map { |k, v| [k, v] }
44
+ end
45
+
46
+ private
47
+
48
+ def translation_set
49
+ @translation_set ||= OrganizationTranslationSets.new(
50
+ current_organization
51
+ ).query.find(params[:translation_set_id])
52
+ end
53
+
54
+ def reject_keys
55
+ @reject_keys ||= (request_keys + existing_keys).uniq
56
+ end
57
+
58
+ def request_keys
59
+ return params[:keys] if params.has_key?(:keys)
60
+
61
+ []
62
+ end
63
+
64
+ def existing_keys
65
+ SetTranslations.new(set).pluck(:key).uniq
66
+ end
67
+
68
+ alias set translation_set
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module TermCustomizer
5
+ module Admin
6
+ # This controller is the abstract class from which all other controllers
7
+ # of this engine inherit.
8
+ class ApplicationController < Decidim::Admin::ApplicationController
9
+ def permission_class_chain
10
+ [Decidim::TermCustomizer::Admin::Permissions] + super
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module TermCustomizer
5
+ module Admin
6
+ class TranslationSetsController < TermCustomizer::Admin::ApplicationController
7
+ include TranslatableAttributes
8
+
9
+ helper_method :collection, :subject_manifests, :blank_constraint
10
+
11
+ def index
12
+ enforce_permission_to :read, :translation_set
13
+ @sets = collection
14
+ end
15
+
16
+ def new
17
+ enforce_permission_to :create, :translation_set
18
+
19
+ @form = form(TranslationSetForm).from_model(
20
+ TranslationSet.new(constraints: [Constraint.new])
21
+ )
22
+ end
23
+
24
+ def create
25
+ enforce_permission_to :create, :translation_set
26
+ @form = form(TranslationSetForm).from_params(
27
+ params,
28
+ current_organization: current_organization
29
+ )
30
+
31
+ CreateTranslationSet.call(@form) do
32
+ on(:ok) do |set|
33
+ flash[:notice] = I18n.t("translation_sets.create.success", scope: "decidim.term_customizer.admin")
34
+ redirect_to translation_set_translations_path(set)
35
+ end
36
+
37
+ on(:invalid) do
38
+ flash.now[:alert] = I18n.t("translation_sets.create.error", scope: "decidim.term_customizer.admin")
39
+ render action: "new"
40
+ end
41
+ end
42
+ end
43
+
44
+ def edit
45
+ enforce_permission_to :update, :translation_set, translation_set: set
46
+ @form = form(TranslationSetForm).from_model(set)
47
+ end
48
+
49
+ def update
50
+ enforce_permission_to :update, :translation_set, translation_set: set
51
+ @form = form(TranslationSetForm).from_params(
52
+ params,
53
+ current_organization: current_organization
54
+ )
55
+
56
+ UpdateTranslationSet.call(@form, set) do
57
+ on(:ok) do
58
+ flash[:notice] = I18n.t("translation_sets.update.success", scope: "decidim.term_customizer.admin")
59
+ redirect_to translation_sets_path
60
+ end
61
+
62
+ on(:invalid) do
63
+ flash.now[:alert] = I18n.t("translation_sets.update.invalid", scope: "decidim.term_customizer.admin")
64
+ render action: "edit"
65
+ end
66
+ end
67
+ end
68
+
69
+ def destroy
70
+ enforce_permission_to :destroy, :translation_set, translation_set: set
71
+ set.destroy!
72
+
73
+ flash[:notice] = I18n.t("translation_sets.destroy.success", scope: "decidim.term_customizer.admin")
74
+
75
+ redirect_to translation_sets_path
76
+ end
77
+
78
+ private
79
+
80
+ def sets
81
+ @sets ||= OrganizationTranslationSets.new(current_organization)
82
+ end
83
+
84
+ alias collection sets
85
+
86
+ def subject_manifests
87
+ @subject_manifests ||= Decidim.participatory_space_manifests.map do |manifest|
88
+ models = manifest.model_class_name.constantize.where(organization: current_organization).map { |p| [translated_attribute(p.title), p.id] }
89
+ next unless models.count.positive?
90
+
91
+ manifest
92
+ end
93
+ end
94
+
95
+ def set
96
+ @set ||= Decidim::TermCustomizer::TranslationSet.find(params[:id])
97
+ end
98
+
99
+ def blank_constraint
100
+ @blank_constraint ||= Admin::TranslationSetConstraintForm.from_model(
101
+ Constraint.new
102
+ )
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end