decidim-term_customizer 0.16.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 (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