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.
- checksums.yaml +7 -0
- data/LICENSE-AGPLv3.txt +661 -0
- data/README.md +180 -0
- data/Rakefile +48 -0
- data/app/assets/config/translation_sets_admin_manifest.js +2 -0
- data/app/assets/javascripts/decidim/term_customizer/admin/constraint_fields.js.es6 +45 -0
- data/app/assets/javascripts/decidim/term_customizer/admin/multifield/component.js.es6 +103 -0
- data/app/assets/javascripts/decidim/term_customizer/admin/multifield.js.es6 +5 -0
- data/app/assets/javascripts/decidim/term_customizer/admin/translation_sets_admin.js.es6 +19 -0
- data/app/assets/javascripts/decidim/term_customizer/admin/translations_admin.js.es6 +72 -0
- data/app/commands/decidim/term_customizer/admin/create_translation.rb +53 -0
- data/app/commands/decidim/term_customizer/admin/create_translation_set.rb +68 -0
- data/app/commands/decidim/term_customizer/admin/import_translation_keys.rb +59 -0
- data/app/commands/decidim/term_customizer/admin/update_translation.rb +65 -0
- data/app/commands/decidim/term_customizer/admin/update_translation_set.rb +61 -0
- data/app/controllers/decidim/term_customizer/admin/add_translations_controller.rb +72 -0
- data/app/controllers/decidim/term_customizer/admin/application_controller.rb +15 -0
- data/app/controllers/decidim/term_customizer/admin/translation_sets_controller.rb +107 -0
- data/app/controllers/decidim/term_customizer/admin/translations_controller.rb +102 -0
- data/app/forms/decidim/term_customizer/admin/translation_form.rb +39 -0
- data/app/forms/decidim/term_customizer/admin/translation_key_import_form.rb +15 -0
- data/app/forms/decidim/term_customizer/admin/translation_set_constraint_form.rb +58 -0
- data/app/forms/decidim/term_customizer/admin/translation_set_form.rb +18 -0
- data/app/forms/decidim/term_customizer/admin/translation_set_subject_component_form.rb +12 -0
- data/app/forms/decidim/term_customizer/admin/translation_set_subject_form.rb +61 -0
- data/app/helpers/decidim/term_customizer/admin/application_helper.rb +13 -0
- data/app/models/decidim/term_customizer/application_record.rb +10 -0
- data/app/models/decidim/term_customizer/constraint.rb +36 -0
- data/app/models/decidim/term_customizer/translation.rb +23 -0
- data/app/models/decidim/term_customizer/translation_set.rb +19 -0
- data/app/permissions/decidim/term_customizer/admin/permissions.rb +66 -0
- data/app/queries/decidim/term_customizer/organization_translation_sets.rb +37 -0
- data/app/queries/decidim/term_customizer/set_translations.rb +21 -0
- data/app/views/decidim/term_customizer/admin/add_translations/index.html.erb +59 -0
- data/app/views/decidim/term_customizer/admin/translation_sets/_constraint_fields.html.erb +58 -0
- data/app/views/decidim/term_customizer/admin/translation_sets/_form.html.erb +29 -0
- data/app/views/decidim/term_customizer/admin/translation_sets/edit.html.erb +9 -0
- data/app/views/decidim/term_customizer/admin/translation_sets/index.html.erb +44 -0
- data/app/views/decidim/term_customizer/admin/translation_sets/new.html.erb +9 -0
- data/app/views/decidim/term_customizer/admin/translations/_form.html.erb +15 -0
- data/app/views/decidim/term_customizer/admin/translations/edit.html.erb +7 -0
- data/app/views/decidim/term_customizer/admin/translations/index.html.erb +52 -0
- data/app/views/decidim/term_customizer/admin/translations/new.html.erb +7 -0
- data/config/locales/en.yml +65 -0
- data/config/locales/fi.yml +65 -0
- data/config/locales/sv.yml +65 -0
- data/lib/decidim/term_customizer/admin.rb +10 -0
- data/lib/decidim/term_customizer/admin_engine.rb +46 -0
- data/lib/decidim/term_customizer/engine.rb +35 -0
- data/lib/decidim/term_customizer/i18n_backend.rb +82 -0
- data/lib/decidim/term_customizer/resolver.rb +108 -0
- data/lib/decidim/term_customizer/test/factories.rb +43 -0
- data/lib/decidim/term_customizer/translation_directory.rb +50 -0
- data/lib/decidim/term_customizer/translation_store.rb +67 -0
- data/lib/decidim/term_customizer/version.rb +8 -0
- data/lib/decidim/term_customizer.rb +21 -0
- metadata +170 -0
@@ -0,0 +1,102 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module TermCustomizer
|
5
|
+
module Admin
|
6
|
+
class TranslationsController < TermCustomizer::Admin::ApplicationController
|
7
|
+
helper_method :collection, :set, :translations, :translation
|
8
|
+
|
9
|
+
def index
|
10
|
+
enforce_permission_to :read, :translation
|
11
|
+
@translations = collection
|
12
|
+
end
|
13
|
+
|
14
|
+
def new
|
15
|
+
enforce_permission_to :create, :translation
|
16
|
+
|
17
|
+
@form = form(TranslationForm).from_model(Translation.new)
|
18
|
+
end
|
19
|
+
|
20
|
+
def create
|
21
|
+
enforce_permission_to :create, :translation
|
22
|
+
@form = form(TranslationForm).from_params(
|
23
|
+
params,
|
24
|
+
current_organization: current_organization,
|
25
|
+
translation_set: set
|
26
|
+
)
|
27
|
+
|
28
|
+
CreateTranslation.call(@form) do
|
29
|
+
on(:ok) do
|
30
|
+
flash[:notice] = I18n.t("translations.create.success", scope: "decidim.term_customizer.admin")
|
31
|
+
redirect_to translation_set_translations_path(set)
|
32
|
+
end
|
33
|
+
|
34
|
+
on(:invalid) do
|
35
|
+
flash.now[:alert] = I18n.t("translations.create.error", scope: "decidim.term_customizer.admin")
|
36
|
+
render action: "new"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def edit
|
42
|
+
enforce_permission_to :update, :translation, translation: translation
|
43
|
+
@form = form(TranslationForm).from_model(translation)
|
44
|
+
end
|
45
|
+
|
46
|
+
def update
|
47
|
+
enforce_permission_to :update, :translation, translation: translation
|
48
|
+
@form = form(TranslationForm).from_params(
|
49
|
+
params,
|
50
|
+
current_organization: current_organization,
|
51
|
+
translation_set: set
|
52
|
+
)
|
53
|
+
|
54
|
+
UpdateTranslation.call(@form, translation) do
|
55
|
+
on(:ok) do
|
56
|
+
flash[:notice] = I18n.t("translations.update.success", scope: "decidim.term_customizer.admin")
|
57
|
+
redirect_to translation_set_translations_path(set)
|
58
|
+
end
|
59
|
+
|
60
|
+
on(:invalid) do
|
61
|
+
flash.now[:alert] = I18n.t("translations.update.invalid", scope: "decidim.term_customizer.admin")
|
62
|
+
render action: "edit"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def destroy
|
68
|
+
enforce_permission_to :destroy, :translation, translation: translation
|
69
|
+
|
70
|
+
# Destroy all locales of the translation key
|
71
|
+
Decidim::TermCustomizer::Translation.where(
|
72
|
+
translation_set: set,
|
73
|
+
key: translation.key
|
74
|
+
).destroy_all
|
75
|
+
|
76
|
+
flash[:notice] = I18n.t("translations.destroy.success", scope: "decidim.term_customizer.admin")
|
77
|
+
|
78
|
+
redirect_to translation_set_translations_path(set)
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
def translation_set
|
84
|
+
@translation_set ||= OrganizationTranslationSets.new(
|
85
|
+
current_organization
|
86
|
+
).query.find(params[:translation_set_id])
|
87
|
+
end
|
88
|
+
|
89
|
+
def translations
|
90
|
+
@translations ||= SetTranslations.new(translation_set, current_locale)
|
91
|
+
end
|
92
|
+
|
93
|
+
def translation
|
94
|
+
@translation ||= Decidim::TermCustomizer::Translation.find(params[:id])
|
95
|
+
end
|
96
|
+
|
97
|
+
alias collection translations
|
98
|
+
alias set translation_set
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module TermCustomizer
|
5
|
+
module Admin
|
6
|
+
class TranslationForm < Decidim::Form
|
7
|
+
include TranslatableAttributes
|
8
|
+
|
9
|
+
mimic :translation
|
10
|
+
|
11
|
+
delegate :translation_set, to: :context, prefix: false, allow_nil: true
|
12
|
+
|
13
|
+
attribute :key, String
|
14
|
+
translatable_attribute :value, String
|
15
|
+
|
16
|
+
validates :key, presence: true
|
17
|
+
validates :key, format: { with: %r{\A([a-z0-9_/]+\.?)*[a-z0-9_/]+\z} }, unless: -> { key.blank? }
|
18
|
+
validates :value, translatable_presence: true
|
19
|
+
validate :key_uniqueness
|
20
|
+
|
21
|
+
def map_model(model)
|
22
|
+
self.value = Hash[Decidim::TermCustomizer::Translation.where(
|
23
|
+
translation_set: model.translation_set,
|
24
|
+
key: model.key
|
25
|
+
).map do |translation|
|
26
|
+
[translation.locale, translation.value]
|
27
|
+
end]
|
28
|
+
end
|
29
|
+
|
30
|
+
def key_uniqueness
|
31
|
+
errors.add(:key, :taken) if translation_set && translation_set.translations.where(
|
32
|
+
locale: I18n.locale,
|
33
|
+
key: key
|
34
|
+
).exists?
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module TermCustomizer
|
5
|
+
module Admin
|
6
|
+
class TranslationKeyImportForm < Decidim::Form
|
7
|
+
mimic :translation
|
8
|
+
|
9
|
+
delegate :translation_set, to: :context, prefix: false, allow_nil: true
|
10
|
+
|
11
|
+
attribute :keys, Array[String]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module TermCustomizer
|
5
|
+
module Admin
|
6
|
+
class TranslationSetConstraintForm < Decidim::Form
|
7
|
+
mimic :constraint
|
8
|
+
|
9
|
+
attribute :subject_manifest, String
|
10
|
+
attribute :subject_model, Array[TermCustomizer::Admin::TranslationSetSubjectForm]
|
11
|
+
attribute :deleted, Boolean, default: false
|
12
|
+
|
13
|
+
def to_param
|
14
|
+
return id if id.present?
|
15
|
+
|
16
|
+
"constraint-id"
|
17
|
+
end
|
18
|
+
|
19
|
+
def map_model(model)
|
20
|
+
self.subject_manifest = model.manifest_name
|
21
|
+
|
22
|
+
return unless model.subject
|
23
|
+
|
24
|
+
self.subject_model = [
|
25
|
+
TermCustomizer::Admin::TranslationSetSubjectForm.from_model(
|
26
|
+
model.subject
|
27
|
+
)
|
28
|
+
]
|
29
|
+
end
|
30
|
+
|
31
|
+
def subject_type
|
32
|
+
return unless subject_form
|
33
|
+
|
34
|
+
subject_form.manifest.try(:model_class_name)
|
35
|
+
end
|
36
|
+
|
37
|
+
def subject
|
38
|
+
return component if component
|
39
|
+
return unless subject_form
|
40
|
+
|
41
|
+
subject_form.subject
|
42
|
+
end
|
43
|
+
|
44
|
+
def component
|
45
|
+
return unless subject_form
|
46
|
+
|
47
|
+
subject_form.component
|
48
|
+
end
|
49
|
+
|
50
|
+
def subject_form
|
51
|
+
@subject_form ||= subject_model.find do |sm|
|
52
|
+
sm.subject_manifest == subject_manifest
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module TermCustomizer
|
5
|
+
module Admin
|
6
|
+
class TranslationSetForm < Decidim::Form
|
7
|
+
include TranslatableAttributes
|
8
|
+
|
9
|
+
mimic :translation_set
|
10
|
+
|
11
|
+
translatable_attribute :name, String
|
12
|
+
attribute :constraints, Array[TermCustomizer::Admin::TranslationSetConstraintForm]
|
13
|
+
|
14
|
+
validates :name, translatable_presence: true
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module TermCustomizer
|
5
|
+
module Admin
|
6
|
+
class TranslationSetSubjectForm < Decidim::Form
|
7
|
+
attribute :subject_manifest, String
|
8
|
+
attribute :subject_id, Integer
|
9
|
+
attribute :component_model, Array[TermCustomizer::Admin::TranslationSetSubjectComponentForm]
|
10
|
+
|
11
|
+
def map_model(model)
|
12
|
+
component = model if model.is_a?(Decidim::Component)
|
13
|
+
subject = if component
|
14
|
+
model.participatory_space
|
15
|
+
else
|
16
|
+
model
|
17
|
+
end
|
18
|
+
|
19
|
+
self.subject_manifest = Decidim.participatory_space_manifests.find do |m|
|
20
|
+
m.model_class_name == subject.class.name
|
21
|
+
end.try(:name)
|
22
|
+
self.subject_id = subject.id
|
23
|
+
|
24
|
+
return unless component
|
25
|
+
|
26
|
+
self.component_model = [
|
27
|
+
TermCustomizer::Admin::TranslationSetSubjectComponentForm.from_params(
|
28
|
+
subject_id: subject.id,
|
29
|
+
component_id: component.id
|
30
|
+
)
|
31
|
+
]
|
32
|
+
end
|
33
|
+
|
34
|
+
def subject
|
35
|
+
return unless manifest
|
36
|
+
|
37
|
+
@subject ||= manifest.model_class_name.constantize.find_by(id: subject_id)
|
38
|
+
end
|
39
|
+
|
40
|
+
def component
|
41
|
+
return unless component_form
|
42
|
+
return unless subject
|
43
|
+
|
44
|
+
subject.components.find_by(id: component_form.component_id)
|
45
|
+
end
|
46
|
+
|
47
|
+
def manifest
|
48
|
+
@manifest ||= Decidim.participatory_space_manifests.find do |m|
|
49
|
+
m.name == subject_manifest.to_sym
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def component_form
|
54
|
+
@component_form ||= component_model.find do |cm|
|
55
|
+
cm.subject_id == subject_id
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module TermCustomizer
|
5
|
+
class Constraint < TermCustomizer::ApplicationRecord
|
6
|
+
self.table_name = "decidim_term_customizer_constraints"
|
7
|
+
|
8
|
+
belongs_to :organization, foreign_key: :decidim_organization_id, class_name: "Decidim::Organization"
|
9
|
+
belongs_to :translation_set, class_name: "Decidim::TermCustomizer::TranslationSet", foreign_key: "translation_set_id"
|
10
|
+
belongs_to :subject, optional: true, polymorphic: true
|
11
|
+
has_many :translations, through: :translation_set
|
12
|
+
|
13
|
+
def component
|
14
|
+
subject if subject.is_a?(Decidim::Component)
|
15
|
+
end
|
16
|
+
|
17
|
+
def space
|
18
|
+
return component.participatory_space if component
|
19
|
+
|
20
|
+
subject
|
21
|
+
end
|
22
|
+
|
23
|
+
def manifest
|
24
|
+
space_class = space ? space.class.name : subject_type
|
25
|
+
|
26
|
+
Decidim.participatory_space_manifests.find do |manifest|
|
27
|
+
manifest.model_class_name == space_class
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def manifest_name
|
32
|
+
manifest.try(:name)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module TermCustomizer
|
5
|
+
class Translation < TermCustomizer::ApplicationRecord
|
6
|
+
self.table_name = "decidim_term_customizer_translations"
|
7
|
+
|
8
|
+
belongs_to :translation_set, class_name: "Decidim::TermCustomizer::TranslationSet", foreign_key: "translation_set_id"
|
9
|
+
has_many :constraints, through: :translation_set
|
10
|
+
|
11
|
+
validates :locale, presence: true
|
12
|
+
validates :key, presence: true
|
13
|
+
validates :key, format: { with: %r{\A([a-z0-9_/]+\.?)*[a-z0-9_/]+\z} }, unless: -> { key.blank? }
|
14
|
+
validates :key, uniqueness: { scope: [:translation_set, :locale] }, unless: -> { key.blank? }
|
15
|
+
|
16
|
+
class << self
|
17
|
+
def available_locales
|
18
|
+
Translation.select("DISTINCT locale").to_a.map { |t| t.locale.to_sym }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module TermCustomizer
|
5
|
+
class TranslationSet < TermCustomizer::ApplicationRecord
|
6
|
+
self.table_name = "decidim_term_customizer_translation_sets"
|
7
|
+
|
8
|
+
has_many :translations,
|
9
|
+
class_name: "Decidim::TermCustomizer::Translation",
|
10
|
+
foreign_key: :translation_set_id,
|
11
|
+
dependent: :destroy
|
12
|
+
|
13
|
+
has_many :constraints,
|
14
|
+
class_name: "Decidim::TermCustomizer::Constraint",
|
15
|
+
foreign_key: :translation_set_id,
|
16
|
+
dependent: :destroy
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module TermCustomizer
|
5
|
+
module Admin
|
6
|
+
class Permissions < Decidim::DefaultPermissions
|
7
|
+
def permissions
|
8
|
+
return permission_action unless user
|
9
|
+
return permission_action unless permission_action.scope == :admin
|
10
|
+
|
11
|
+
unless user.admin?
|
12
|
+
disallow!
|
13
|
+
return permission_action
|
14
|
+
end
|
15
|
+
|
16
|
+
if read_admin_dashboard_action?
|
17
|
+
allow!
|
18
|
+
return permission_action
|
19
|
+
end
|
20
|
+
|
21
|
+
allowed_translation_set_action?
|
22
|
+
allowed_translation_action?
|
23
|
+
|
24
|
+
permission_action
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def translation_set
|
30
|
+
@translation_set ||= context.fetch(:translation_set, nil)
|
31
|
+
end
|
32
|
+
|
33
|
+
def translation
|
34
|
+
@translation ||= context.fetch(:translation, nil)
|
35
|
+
end
|
36
|
+
|
37
|
+
def allowed_translation_set_action?
|
38
|
+
return unless permission_action.subject == :translation_set
|
39
|
+
|
40
|
+
case permission_action.action
|
41
|
+
when :create, :read
|
42
|
+
allow!
|
43
|
+
when :update, :destroy
|
44
|
+
toggle_allow(translation_set.present?)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def allowed_translation_action?
|
49
|
+
return unless permission_action.subject == :translation
|
50
|
+
|
51
|
+
case permission_action.action
|
52
|
+
when :create, :read
|
53
|
+
allow!
|
54
|
+
when :update, :destroy
|
55
|
+
toggle_allow(translation.present?)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def read_admin_dashboard_action?
|
60
|
+
permission_action.action == :read &&
|
61
|
+
permission_action.subject == :admin_dashboard
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|