decidim-decidim_awesome 0.11.4 → 0.12.3
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 +4 -4
- data/CHANGELOG.md +47 -6
- data/README.md +33 -39
- data/Rakefile +12 -0
- data/app/cells/concerns/decidim/decidim_awesome/global_menu_cell_override.rb +14 -2
- data/app/cells/concerns/decidim/decidim_awesome/proposal_l_cell_override.rb +5 -4
- data/app/cells/decidim/decidim_awesome/voting/voting_cards_proposal/show.erb +4 -4
- data/app/cells/decidim/decidim_awesome/voting/voting_cards_proposal/vote_block_for.erb +1 -1
- data/app/cells/decidim/decidim_awesome/voting/voting_cards_proposal_cell.rb +3 -5
- data/app/commands/concerns/decidim/decidim_awesome/system/{register_organization_override.rb → create_organization_override.rb} +1 -1
- data/app/commands/concerns/decidim/decidim_awesome/update_account_override.rb +4 -4
- data/app/commands/decidim/decidim_awesome/admin/create_constraint.rb +1 -1
- data/app/commands/decidim/decidim_awesome/create_editor_image.rb +2 -2
- data/app/controllers/concerns/decidim/decidim_awesome/admin/maintenance_context.rb +0 -28
- data/app/controllers/concerns/decidim/decidim_awesome/needs_hashcash.rb +41 -0
- data/app/controllers/concerns/decidim/decidim_awesome/not_found_redirect.rb +2 -2
- data/app/controllers/decidim/decidim_awesome/admin/admin_authorizations_controller.rb +2 -2
- data/app/controllers/decidim/decidim_awesome/admin/checks_controller.rb +0 -10
- data/app/controllers/decidim/decidim_awesome/admin/config_controller.rb +2 -1
- data/app/controllers/decidim/decidim_awesome/admin/custom_redirects_controller.rb +1 -2
- data/app/controllers/decidim/decidim_awesome/admin/hashcash_controller.rb +39 -0
- data/app/controllers/decidim/decidim_awesome/admin/menu_hacks_controller.rb +1 -1
- data/app/controllers/decidim/decidim_awesome/admin/{maintenance_controller.rb → private_data_controller.rb} +9 -9
- data/app/controllers/decidim/decidim_awesome/utils_controller.rb +17 -0
- data/app/forms/concerns/decidim/decidim_awesome/proposals/{proposal_wizard_create_step_form_override.rb → proposal_form_customizations.rb} +1 -1
- data/app/forms/concerns/decidim/decidim_awesome/proposals/proposal_form_override.rb +7 -1
- data/app/forms/concerns/decidim/decidim_awesome/system/organization_form_override.rb +2 -2
- data/app/forms/decidim/decidim_awesome/admin/config_form.rb +13 -0
- data/app/helpers/decidim/decidim_awesome/admin/config_constraints_helpers.rb +1 -1
- data/app/helpers/decidim/decidim_awesome/map_helper.rb +4 -2
- data/app/models/decidim/decidim_awesome/paper_trail_version.rb +1 -1
- data/app/overrides/decidim/devise/registrations/new/add_hashcash.html.erb.deface +3 -0
- data/app/overrides/decidim/devise/sessions/new/add_hashcash.html.erb.deface +3 -0
- data/app/overrides/layouts/decidim/_head/add_awesome_custom_styles.html.erb.deface +3 -0
- data/app/overrides/layouts/decidim/_head/add_awesome_tags.html.erb.deface +0 -2
- data/app/packs/entrypoints/decidim_admin_decidim_awesome_search_form.scss +1 -0
- data/app/packs/entrypoints/decidim_decidim_awesome_hashcash.js +4 -0
- data/app/packs/src/decidim/decidim_awesome/admin/auto_edit.js +10 -6
- data/app/packs/src/decidim/decidim_awesome/admin/custom_fields_builder.js +4 -2
- data/app/packs/src/decidim/decidim_awesome/admin/verifications.js +6 -3
- data/app/packs/src/decidim/decidim_awesome/awesome_map/api/proposals_fetcher.js +1 -1
- data/app/packs/src/decidim/decidim_awesome/awesome_map/controllers/controller.js +1 -1
- data/app/packs/src/decidim/decidim_awesome/awesome_map/controllers/proposals_controller.js +1 -1
- data/app/packs/src/decidim/decidim_awesome/awesome_map/controls_ui.js +6 -6
- data/app/packs/src/decidim/decidim_awesome/awesome_map/load_map.js +1 -1
- data/app/packs/src/decidim/decidim_awesome/forms/autosave.js +3 -3
- data/app/packs/src/decidim/decidim_awesome/forms/custom_fields_renderer.js +1 -113
- data/app/packs/src/decidim/decidim_awesome/proposals/images.js +1 -1
- data/app/packs/src/vendor/form_builder_langs/ar-SA.lang +111 -0
- data/app/packs/src/vendor/form_builder_langs/ar-TN.lang +94 -0
- data/app/packs/src/vendor/form_builder_langs/ca-ES.lang +110 -0
- data/app/packs/src/vendor/form_builder_langs/cs-CZ.lang +105 -0
- data/app/packs/src/vendor/form_builder_langs/da-DK.lang +110 -0
- data/app/packs/src/vendor/form_builder_langs/de-DE.lang +109 -0
- data/app/packs/src/vendor/form_builder_langs/el-GR.lang +110 -0
- data/app/packs/src/vendor/form_builder_langs/en-US.lang +117 -0
- data/app/packs/src/vendor/form_builder_langs/es-ES.lang +103 -0
- data/app/packs/src/vendor/form_builder_langs/fa-IR.lang +108 -0
- data/app/packs/src/vendor/form_builder_langs/fi-FI.lang +107 -0
- data/app/packs/src/vendor/form_builder_langs/fr-FR.lang +117 -0
- data/app/packs/src/vendor/form_builder_langs/he-IL.lang +108 -0
- data/app/packs/src/vendor/form_builder_langs/hi-IN.lang +110 -0
- data/app/packs/src/vendor/form_builder_langs/hu-HU.lang +108 -0
- data/app/packs/src/vendor/form_builder_langs/id-ID.lang +110 -0
- data/app/packs/src/vendor/form_builder_langs/it-IT.lang +107 -0
- data/app/packs/src/vendor/form_builder_langs/ja-JP.lang +108 -0
- data/app/packs/src/vendor/form_builder_langs/my-MM.lang +108 -0
- data/app/packs/src/vendor/form_builder_langs/nb-NO.lang +94 -0
- data/app/packs/src/vendor/form_builder_langs/nl-NL.lang +94 -0
- data/app/packs/src/vendor/form_builder_langs/pl-PL.lang +122 -0
- data/app/packs/src/vendor/form_builder_langs/pt-BR.lang +110 -0
- data/app/packs/src/vendor/form_builder_langs/pu-IN.lang +110 -0
- data/app/packs/src/vendor/form_builder_langs/qz-MM.lang +108 -0
- data/app/packs/src/vendor/form_builder_langs/ro-RO.lang +94 -0
- data/app/packs/src/vendor/form_builder_langs/ru-RU.lang +110 -0
- data/app/packs/src/vendor/form_builder_langs/sl-SI.lang +110 -0
- data/app/packs/src/vendor/form_builder_langs/th-TH.lang +111 -0
- data/app/packs/src/vendor/form_builder_langs/tr-TR.lang +115 -0
- data/app/packs/src/vendor/form_builder_langs/uk-UA.lang +108 -0
- data/app/packs/src/vendor/form_builder_langs/vi-VN.lang +94 -0
- data/app/packs/src/vendor/form_builder_langs/zh-CN.lang +100 -0
- data/app/packs/src/vendor/form_builder_langs/zh-TW.lang +94 -0
- data/app/packs/src/vendor/hashcash.js +83 -0
- data/app/packs/src/vendor/sha1.js +143 -0
- data/app/packs/src/vendor/stamp.js +50 -0
- data/app/packs/stylesheets/decidim/decidim_awesome/admin/admin_accountability.scss +67 -0
- data/app/packs/stylesheets/decidim/decidim_awesome/forms/autosave.scss +2 -12
- data/app/permissions/decidim/decidim_awesome/permissions.rb +3 -2
- data/app/presenters/decidim/decidim_awesome/private_data_presenter.rb +2 -2
- data/app/uploaders/decidim/decidim_awesome/image_uploader.rb +12 -0
- data/app/views/decidim/decidim_awesome/admin/admin_accountability/index.html.erb +5 -4
- data/app/views/decidim/decidim_awesome/admin/admin_authorizations/callout.html.erb +2 -2
- data/app/views/decidim/decidim_awesome/admin/admin_authorizations/conflict.html.erb +4 -4
- data/app/views/decidim/decidim_awesome/admin/admin_authorizations/edit.html.erb +6 -5
- data/app/views/decidim/decidim_awesome/admin/checks/index.html.erb +6 -6
- data/app/views/decidim/decidim_awesome/admin/config/_autoedit_box_label.html.erb +2 -2
- data/app/views/decidim/decidim_awesome/admin/config/_constraints.html.erb +3 -3
- data/app/views/decidim/decidim_awesome/admin/config/_form_admins.html.erb +4 -3
- data/app/views/decidim/decidim_awesome/admin/config/_form_editors.html.erb +1 -1
- data/app/views/decidim/decidim_awesome/admin/config/_form_proposal_custom_fields.html.erb +4 -4
- data/app/views/decidim/decidim_awesome/admin/config/_form_scoped_styles.html.erb +3 -3
- data/app/views/decidim/decidim_awesome/admin/config/_form_surveys.html.erb +40 -2
- data/app/views/decidim/decidim_awesome/admin/config/_form_verifications.html.erb +1 -1
- data/app/views/decidim/decidim_awesome/admin/hashcash/_filters.html.erb +55 -0
- data/app/views/decidim/decidim_awesome/admin/hashcash/index.html.erb +33 -0
- data/app/views/decidim/decidim_awesome/admin/hashcash/ip_addresses.html.erb +29 -0
- data/app/views/decidim/decidim_awesome/admin/hashcash/show.html.erb +42 -0
- data/app/views/decidim/decidim_awesome/admin/menu_hacks/index.html.erb +2 -2
- data/app/views/decidim/decidim_awesome/admin/{maintenance → private_data}/_private_data.html.erb +2 -2
- data/app/views/decidim/decidim_awesome/admin/{maintenance/show.html.erb → private_data/index.html.erb} +2 -3
- data/app/views/decidim/decidim_awesome/admin/proposals/_private_body.html.erb +1 -1
- data/app/views/decidim/decidim_awesome/admin/shared/_filters_with_date.html.erb +41 -32
- data/app/views/decidim/decidim_awesome/amendments/_modal.html.erb +2 -2
- data/app/views/decidim/decidim_awesome/hashcash/_hidden_field.html.erb +5 -0
- data/app/views/decidim/decidim_awesome/map_component/map/_map_template.html.erb +1 -1
- data/app/views/layouts/decidim/decidim_awesome/_awesome_config.html.erb +2 -2
- data/app/views/layouts/decidim/decidim_awesome/admin/maintenance.html.erb +2 -11
- data/config/assets.rb +3 -1
- data/config/i18n-tasks.yml +1 -0
- data/config/locales/ca.yml +69 -30
- data/config/locales/cs.yml +68 -29
- data/config/locales/de.yml +67 -28
- data/config/locales/en.yml +81 -32
- data/config/locales/es.yml +68 -29
- data/config/locales/eu.yml +31 -31
- data/config/locales/fr.yml +82 -31
- data/config/locales/ja.yml +31 -31
- data/lib/decidim/decidim_awesome/admin_engine.rb +8 -5
- data/lib/decidim/decidim_awesome/awesome.rb +49 -27
- data/lib/decidim/decidim_awesome/checksums.yml +47 -42
- data/lib/decidim/decidim_awesome/context_analyzers/request_analyzer.rb +2 -2
- data/lib/decidim/decidim_awesome/engine.rb +16 -6
- data/lib/decidim/decidim_awesome/menu.rb +151 -138
- data/lib/decidim/decidim_awesome/test/initializer.rb +4 -1
- data/lib/decidim/decidim_awesome/test/shared_examples/box_label_editor_examples.rb +14 -14
- data/lib/decidim/decidim_awesome/test/shared_examples/config_examples.rb +2 -4
- data/lib/decidim/decidim_awesome/test/shared_examples/custom_fields_examples.rb +8 -8
- data/lib/decidim/decidim_awesome/test/shared_examples/custom_styles_examples.rb +6 -6
- data/lib/decidim/decidim_awesome/test/shared_examples/editor_examples.rb +5 -4
- data/lib/decidim/decidim_awesome/test/shared_examples/scoped_admins_examples.rb +5 -5
- data/lib/decidim/decidim_awesome/test/shared_examples/summary_examples.rb +16 -9
- data/lib/decidim/decidim_awesome/version.rb +2 -2
- data/lib/decidim/decidim_awesome.rb +0 -1
- data/lib/tasks/decidim_awesome_upgrade_tasks.rake +4 -5
- data/package.json +9 -18
- metadata +82 -26
- data/app/jobs/decidim/decidim_awesome/migrate_legacy_images_job.rb +0 -107
- data/app/uploaders/decidim/cw/decidim_awesome/image_uploader.rb +0 -26
- data/config/rubocop/disabled.yml +0 -11
- data/config/rubocop/faker.yml +0 -480
- data/config/rubocop/rails.yml +0 -88
- data/config/rubocop/rspec.yml +0 -65
- data/config/rubocop/ruby.yml +0 -1210
- data/lib/decidim/decidim_awesome/content_parsers/editor_images_parser.rb +0 -39
- data/lib/tasks/decidim_awesome_active_storage_migrations_tasks.rake +0 -35
- /data/{app/middleware/decidim/decidim_awesome → lib/decidim/decidim_awesome/middleware}/current_config.rb +0 -0
@@ -6,7 +6,7 @@ module Decidim
|
|
6
6
|
module DecidimAwesome
|
7
7
|
module Admin
|
8
8
|
# System compatibility analyzer
|
9
|
-
class
|
9
|
+
class PrivateDataController < DecidimAwesome::Admin::ApplicationController
|
10
10
|
include NeedsAwesomeConfig
|
11
11
|
include MaintenanceContext
|
12
12
|
include Decidim::Admin::Filterable
|
@@ -19,36 +19,36 @@ module Decidim
|
|
19
19
|
enforce_permission_to :edit_config, :private_data, private_data:
|
20
20
|
end
|
21
21
|
|
22
|
-
def
|
22
|
+
def index
|
23
23
|
respond_to do |format|
|
24
24
|
format.json do
|
25
25
|
render json: private_data_finder.for(params[:resources].to_s.split(",")).map { |resource| present(resource) }
|
26
26
|
end
|
27
27
|
format.all do
|
28
|
-
render :
|
28
|
+
render :index
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
-
def
|
33
|
+
def destroy
|
34
34
|
if private_data && private_data.total.to_i.positive?
|
35
35
|
Decidim::ActionLogger.log("destroy_private_data", current_user, resource, nil, count: private_data.total)
|
36
36
|
|
37
37
|
Lock.new(current_organization).get!(resource)
|
38
38
|
DestroyPrivateDataJob.set(wait: 1.second).perform_later(resource)
|
39
39
|
end
|
40
|
-
redirect_to decidim_admin_decidim_awesome.
|
41
|
-
notice: I18n.t("
|
40
|
+
redirect_to decidim_admin_decidim_awesome.private_data_path,
|
41
|
+
notice: I18n.t("destroying", scope: "decidim.decidim_awesome.admin.private_data.private_data", title: present(resource).name)
|
42
42
|
end
|
43
43
|
|
44
44
|
private
|
45
45
|
|
46
46
|
def resource
|
47
|
-
@resource ||= Component.find_by(id: params[:
|
47
|
+
@resource ||= Component.find_by(id: params[:id])
|
48
48
|
end
|
49
49
|
|
50
50
|
def private_data
|
51
|
-
@private_data ||=
|
51
|
+
@private_data ||= present(resource) if resource
|
52
52
|
end
|
53
53
|
|
54
54
|
def collection
|
@@ -60,7 +60,7 @@ module Decidim
|
|
60
60
|
end
|
61
61
|
|
62
62
|
def present(resource)
|
63
|
-
|
63
|
+
PrivateDataPresenter.new(resource)
|
64
64
|
end
|
65
65
|
|
66
66
|
def private_data_finder
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module DecidimAwesome
|
5
|
+
# Abstract component class for components without any admin controllers (only settings)
|
6
|
+
class UtilsController < DecidimAwesome::ApplicationController
|
7
|
+
def form_builder_i18n
|
8
|
+
lang = I18n.locale
|
9
|
+
folder = "app/packs/src/vendor/form_builder_langs/"
|
10
|
+
file = Decidim::DecidimAwesome::Engine.root.join(folder, "#{lang}.lang")
|
11
|
+
file = Dir[Decidim::DecidimAwesome::Engine.root.join(folder, "#{lang}-*.lang")].first unless File.exist?(file)
|
12
|
+
file = Decidim::DecidimAwesome::Engine.root.join(folder, "en-US.lang") unless file && File.exist?(file)
|
13
|
+
render plain: File.read(file)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -8,7 +8,13 @@ module Decidim
|
|
8
8
|
|
9
9
|
included do
|
10
10
|
alias_method :decidim_original_map_model, :map_model
|
11
|
-
attribute :private_body,
|
11
|
+
attribute :private_body, Decidim::Attributes::RichText
|
12
|
+
|
13
|
+
if name == "Decidim::Proposals::ProposalForm"
|
14
|
+
# the original decidim uses CleanString, as no images are allowed for non admins
|
15
|
+
# The RichText attribute transforms signed_id blobs to ObjectIDs
|
16
|
+
attribute :body, Decidim::Attributes::RichText
|
17
|
+
end
|
12
18
|
|
13
19
|
def map_model(model)
|
14
20
|
decidim_original_map_model(model)
|
@@ -9,7 +9,7 @@ module Decidim
|
|
9
9
|
included do
|
10
10
|
alias_method :decidim_original_map_model, :map_model
|
11
11
|
|
12
|
-
attribute :awesome_admins_available_authorizations,
|
12
|
+
attribute :awesome_admins_available_authorizations, [String]
|
13
13
|
|
14
14
|
def map_model(model)
|
15
15
|
decidim_original_map_model(model)
|
@@ -19,7 +19,7 @@ module Decidim
|
|
19
19
|
def clean_awesome_admins_available_authorizations
|
20
20
|
return unless awesome_admins_available_authorizations
|
21
21
|
|
22
|
-
awesome_admins_available_authorizations.
|
22
|
+
awesome_admins_available_authorizations.compact_blank
|
23
23
|
end
|
24
24
|
|
25
25
|
private
|
@@ -20,6 +20,10 @@ module Decidim
|
|
20
20
|
attribute :user_timezone, Boolean
|
21
21
|
attribute :force_authorization_after_login, Array
|
22
22
|
attribute :force_authorization_with_any_method, Boolean
|
23
|
+
attribute :hashcash_signup, Boolean
|
24
|
+
attribute :hashcash_signup_bits, Integer, default: Decidim::DecidimAwesome.hashcash_signup_bits
|
25
|
+
attribute :hashcash_login, Boolean
|
26
|
+
attribute :hashcash_login_bits, Integer, default: Decidim::DecidimAwesome.hashcash_login_bits
|
23
27
|
translatable_attribute :force_authorization_help_text, String
|
24
28
|
attribute :scoped_admins, Hash
|
25
29
|
attribute :menu, [MenuForm]
|
@@ -49,6 +53,8 @@ module Decidim
|
|
49
53
|
validates :validate_body_min_length, presence: true, numericality: { greater_than_or_equal_to: 0 }
|
50
54
|
validates :validate_body_max_caps_percent, presence: true, numericality: { greater_than_or_equal_to: 0, less_than_or_equal_to: 100 }
|
51
55
|
validates :validate_body_max_marks_together, presence: true, numericality: { greater_than_or_equal_to: 1 }
|
56
|
+
validates :hashcash_signup_bits, presence: true, numericality: { greater_than_or_equal_to: 10, less_than_or_equal_to: 50 }
|
57
|
+
validates :hashcash_login_bits, presence: true, numericality: { greater_than_or_equal_to: 10, less_than_or_equal_to: 50 }
|
52
58
|
validate :force_authorization_after_login_is_valid
|
53
59
|
# TODO: validate non general admins are here
|
54
60
|
|
@@ -57,6 +63,7 @@ module Decidim
|
|
57
63
|
instance.force_authorization_after_login = instance.force_authorization_after_login.compact_blank if instance.force_authorization_after_login.present?
|
58
64
|
instance.valid_keys = extract_valid_keys_from_params(params)
|
59
65
|
instance.sanitize_labels!
|
66
|
+
instance.sanitize_arrays!
|
60
67
|
instance
|
61
68
|
end
|
62
69
|
|
@@ -135,6 +142,12 @@ module Decidim
|
|
135
142
|
end
|
136
143
|
end
|
137
144
|
|
145
|
+
def sanitize_arrays!
|
146
|
+
scoped_admins.transform_values! do |code|
|
147
|
+
code.is_a?(Array) ? code.compact_blank : code
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
138
151
|
private
|
139
152
|
|
140
153
|
def force_authorization_after_login_is_valid
|
@@ -8,7 +8,7 @@ module Decidim
|
|
8
8
|
|
9
9
|
include Decidim::TranslatableAttributes
|
10
10
|
|
11
|
-
delegate :menus, :config_enabled?, to: "Decidim::DecidimAwesome::Menu"
|
11
|
+
delegate :menus, :main_path_for, :config_enabled?, to: "Decidim::DecidimAwesome::Menu"
|
12
12
|
|
13
13
|
def check(status)
|
14
14
|
content_tag(:span, icon(status ? "check-line" : "close-line", class: "inline-block", aria_label: status, role: "img"), class: "fill-#{status ? "success" : "alert"}")
|
@@ -10,7 +10,7 @@ module Decidim
|
|
10
10
|
end
|
11
11
|
|
12
12
|
# rubocop:disable Metrics/CyclomaticComplexity
|
13
|
-
# rubocop:disable Metrics/PerceivedComplexity
|
13
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
14
14
|
def awesome_map_for(components, &)
|
15
15
|
return unless map_utility_dynamic
|
16
16
|
|
@@ -57,7 +57,7 @@ module Decidim
|
|
57
57
|
end
|
58
58
|
end
|
59
59
|
# rubocop:enable Metrics/CyclomaticComplexity
|
60
|
-
# rubocop:enable Metrics/PerceivedComplexity
|
60
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
61
61
|
|
62
62
|
def step_settings
|
63
63
|
settings_source.try(:current_settings)
|
@@ -71,6 +71,7 @@ module Decidim
|
|
71
71
|
try(:current_component) || self
|
72
72
|
end
|
73
73
|
|
74
|
+
# rubocop:disable Rails/HelperInstanceVariable
|
74
75
|
def current_categories(categories)
|
75
76
|
return @current_categories if @current_categories
|
76
77
|
|
@@ -114,6 +115,7 @@ module Decidim
|
|
114
115
|
color: format("#%02x%02x%02x", r, g, b)
|
115
116
|
)
|
116
117
|
end
|
118
|
+
# rubocop:enable Rails/HelperInstanceVariable
|
117
119
|
|
118
120
|
# HSV values in [0..1[
|
119
121
|
# returns [r, g, b] values from 0 to 255
|
@@ -20,7 +20,7 @@ module Decidim
|
|
20
20
|
# add users that might have been completly destroyed in any organization
|
21
21
|
relevant_user_ids += user_ids_from_object_changes - Decidim::User.select("id").where(id: user_ids_from_object_changes).pluck(:id)
|
22
22
|
|
23
|
-
role_changes.where("object_changes ~ ANY (array[?])", relevant_user_ids.map { |id| "decidim_user_id:\n- ?\n- #{id}" })
|
23
|
+
role_changes.where("object_changes ~ ANY (array[?])", relevant_user_ids.map { |id| "decidim_user_id:\n- ?\n- #{id}(?!\\d)" })
|
24
24
|
}
|
25
25
|
|
26
26
|
scope :in_organization, lambda { |organization|
|
@@ -1,7 +1,5 @@
|
|
1
1
|
<!-- insert_after "erb[loud]:contains('append_stylesheet_pack_tag')" -->
|
2
2
|
|
3
3
|
<% append_stylesheet_pack_tag "decidim_decidim_awesome", media: "all" %>
|
4
|
-
<%= render(partial: "layouts/decidim/decidim_awesome/custom_styles") if awesome_scoped_styles.present? %>
|
5
|
-
|
6
4
|
<% append_javascript_pack_tag "decidim_decidim_awesome", defer: false %>
|
7
5
|
<% append_javascript_pack_tag("decidim_decidim_awesome_custom_fields") if Decidim::DecidimAwesome.enabled?(:proposal_custom_fields) %>
|
@@ -0,0 +1 @@
|
|
1
|
+
@import "stylesheets/decidim/decidim_awesome/admin/admin_accountability";
|
@@ -14,8 +14,8 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
14
14
|
|
15
15
|
const key = target.dataset.key;
|
16
16
|
const attribute = target.dataset.var;
|
17
|
-
const
|
18
|
-
const
|
17
|
+
const inputFields = document.querySelectorAll(`[name="config[${attribute}][${key}]"]`);
|
18
|
+
const multipleFields = document.querySelectorAll(`[name="config[${attribute}][${key}][]"]`);
|
19
19
|
const container = document.querySelector(`.js-box-container[data-key="${key}"]`);
|
20
20
|
const deleteBox = container.querySelector(".awesome-auto-delete");
|
21
21
|
|
@@ -32,11 +32,15 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
32
32
|
const rebuildHtml = (result) => {
|
33
33
|
rebuildLabel(result.key, result.scope);
|
34
34
|
constraints.outerHTML = result.html;
|
35
|
-
if (
|
36
|
-
|
35
|
+
if (inputFields.length > 0) {
|
36
|
+
inputFields.forEach((inputField) => {
|
37
|
+
inputField.setAttribute("name", `config[${attribute}][${result.key}]`);
|
38
|
+
});
|
37
39
|
}
|
38
|
-
if (
|
39
|
-
|
40
|
+
if (multipleFields.length > 0) {
|
41
|
+
multipleFields.forEach((multipleField) => {
|
42
|
+
multipleField.setAttribute("name", `config[${attribute}][${result.key}][]`);
|
43
|
+
});
|
40
44
|
}
|
41
45
|
container.dataset.key = result.key;
|
42
46
|
container.setAttribute("data-key", result.key);
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import "formBuilder/dist/form-builder.min.js";
|
2
2
|
import "src/decidim/decidim_awesome/forms/rich_text_plugin"
|
3
|
+
|
3
4
|
// formBuilder uses jquery-ui-sortable which is a very dirty npm package with no neat source code available, and causes problems with the webpacker configuration of Decidim.
|
4
5
|
// For the moment, we'll remove the sortable functionality with a dummy jQuery plugin until we find another sortable plugin (or keep it disabled for good)
|
5
6
|
jQuery.fn.sortable = () => {}
|
@@ -10,6 +11,7 @@ $(() => {
|
|
10
11
|
$(".awesome-edit-config .proposal_custom_fields_editor").each((_idx, el) => {
|
11
12
|
const key = $(el).closest(".proposal_custom_fields_container").data("key");
|
12
13
|
const configVar = $(el).closest(".proposal_custom_fields_container").data("var");
|
14
|
+
|
13
15
|
// DOCS: https://formbuilder.online/docs
|
14
16
|
window.CustomFieldsBuilders.push({
|
15
17
|
el: el,
|
@@ -17,8 +19,8 @@ $(() => {
|
|
17
19
|
var: configVar,
|
18
20
|
config: {
|
19
21
|
i18n: {
|
20
|
-
locale:
|
21
|
-
location:
|
22
|
+
locale: window.DecidimAwesome.currentLocale,
|
23
|
+
location: window.DecidimAwesome.formBuilderLangsLocation
|
22
24
|
},
|
23
25
|
formData: $(`input[name="config[${configVar}][${key}]"]`).val(),
|
24
26
|
disableFields: ["button", "file"],
|
@@ -17,10 +17,13 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
17
17
|
});
|
18
18
|
|
19
19
|
|
20
|
-
document.body.addEventListener("ajax:
|
21
|
-
|
20
|
+
document.body.addEventListener("ajax:error", (responseText) => {
|
21
|
+
container.innerHTML = `<div>${responseText.detail[0]}</div>`;
|
22
|
+
});
|
23
|
+
document.body.addEventListener("ajax:success", (responseText) => {
|
24
|
+
// console.log("ajax:success", responseText);
|
25
|
+
const response = responseText.detail[0];
|
22
26
|
const button = document.querySelector(`[data-verification-handler="${response.handler}"][data-verification-user-id="${response.userId}"]`);
|
23
|
-
// console.log("ajax:complete", responseText, "response", response, "button", button);
|
24
27
|
container.innerHTML = response.message;
|
25
28
|
|
26
29
|
if (response.granted) {
|
@@ -58,7 +58,7 @@ export default class ProposalsFetcher extends Fetcher {
|
|
58
58
|
|
59
59
|
decorateNode(node) {
|
60
60
|
super.decorateNode(node);
|
61
|
-
node.authorName = node.author && node.author.name || window.DecidimAwesome.
|
61
|
+
node.authorName = node.author && node.author.name || window.DecidimAwesome.i18n.officialAuthor;
|
62
62
|
node.humanState = window.AwesomeMapProposalTexts[node.state];
|
63
63
|
switch (node.state) {
|
64
64
|
case "accepted":
|
@@ -16,7 +16,7 @@ export default class Controller {
|
|
16
16
|
getLabel() {
|
17
17
|
let text = this.component.name;
|
18
18
|
if (!text || this.awesomeMap.config.menu.mergeComponents) {
|
19
|
-
text = window.DecidimAwesome.
|
19
|
+
text = window.DecidimAwesome.i18n[this.component.type];
|
20
20
|
}
|
21
21
|
return `<span class="awesome_map-component" id="awesome_map-component_${this.component.id}" title="0" data-layer="${this.component.type}">${text}</span>`
|
22
22
|
}
|
@@ -16,7 +16,7 @@ export default class ProposalsController extends Controller {
|
|
16
16
|
// add control layer for amendments if any
|
17
17
|
if (this.awesomeMap.config.menu.amendments && this.component.amendments && !this.awesomeMap.layers.amendments) {
|
18
18
|
this.awesomeMap.layers.amendments = {
|
19
|
-
label: `<span class="awesome_map-component" id="awesome_map-amendments_${this.component.id}" title="0" data-layer="amendments">${window.DecidimAwesome.
|
19
|
+
label: `<span class="awesome_map-component" id="awesome_map-amendments_${this.component.id}" title="0" data-layer="amendments">${window.DecidimAwesome.i18n.amendments}</span>`,
|
20
20
|
group: new L.FeatureGroup.SubGroup(this.awesomeMap.cluster)
|
21
21
|
}
|
22
22
|
this.awesomeMap.controls.main.addOverlay(this.awesomeMap.layers.amendments.group, this.awesomeMap.layers.amendments.label);
|
@@ -82,8 +82,8 @@ export default class ControlsUI {
|
|
82
82
|
addSearchControls() {
|
83
83
|
const section = this.main.getContainer().querySelector(".leaflet-control-layers-list");
|
84
84
|
if (section) {
|
85
|
-
section.insertAdjacentHTML("beforeend", `<div id="awesome_map-categories-control" class="active"><b class="awesome_map-title-control">${window.DecidimAwesome.
|
86
|
-
<div id="awesome_map-hashtags-control"><b class="awesome_map-title-control">${window.DecidimAwesome.
|
85
|
+
section.insertAdjacentHTML("beforeend", `<div id="awesome_map-categories-control" class="active"><b class="awesome_map-title-control">${window.DecidimAwesome.i18n.categories}</b><div class="categories-container"></div></div>
|
86
|
+
<div id="awesome_map-hashtags-control"><b class="awesome_map-title-control">${window.DecidimAwesome.i18n.hashtags}</b><div class="hashtags-container"></div><a href="#" class="awesome_map-toggle_all_tags">${window.DecidimAwesome.i18n.selectDeselectAll}</a></div>`);
|
87
87
|
} else {
|
88
88
|
console.error("Can't find the section to insert the controls");
|
89
89
|
}
|
@@ -158,7 +158,7 @@ export default class ControlsUI {
|
|
158
158
|
|
159
159
|
const label = document.querySelector(`label.awesome_map-hashtag-${hashtag.tag}`);
|
160
160
|
// update number of items
|
161
|
-
label.setAttribute("title", `${parseInt(label.title || 0, 10) + 1} ${window.DecidimAwesome.
|
161
|
+
label.setAttribute("title", `${parseInt(label.title || 0, 10) + 1} ${window.DecidimAwesome.i18n.items}`);
|
162
162
|
});
|
163
163
|
}
|
164
164
|
}
|
@@ -171,12 +171,12 @@ export default class ControlsUI {
|
|
171
171
|
if (label) {
|
172
172
|
label.style.display = "block";
|
173
173
|
// update number of items
|
174
|
-
label.setAttribute("title", `${parseInt(label.title || 0, 10) + 1} ${window.DecidimAwesome.
|
174
|
+
label.setAttribute("title", `${parseInt(label.title || 0, 10) + 1} ${window.DecidimAwesome.i18n.items}`);
|
175
175
|
}
|
176
176
|
if (parent) {
|
177
177
|
// show parent if apply
|
178
178
|
parent.style.display = "block"
|
179
|
-
parent.setAttribute("title", `${parseInt(parent.title || 0, 10) + 1} ${window.DecidimAwesome.
|
179
|
+
parent.setAttribute("title", `${parseInt(parent.title || 0, 10) + 1} ${window.DecidimAwesome.i18n.items}`);
|
180
180
|
}
|
181
181
|
}
|
182
182
|
|
@@ -224,7 +224,7 @@ export default class ControlsUI {
|
|
224
224
|
updateStats(uid, total) {
|
225
225
|
// update component stats
|
226
226
|
const $component = $(`#awesome_map-${uid}`);
|
227
|
-
$component.attr("title", `${total} ${window.DecidimAwesome.
|
227
|
+
$component.attr("title", `${total} ${window.DecidimAwesome.i18n.items}`);
|
228
228
|
}
|
229
229
|
|
230
230
|
_indeterminateParentInput(cat) {
|
@@ -25,7 +25,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
25
25
|
const dataset = document.getElementById("awesome-map").dataset;
|
26
26
|
const config = {
|
27
27
|
length: parse(dataset.truncate) || 254,
|
28
|
-
center: sanitizeCenter(
|
28
|
+
center: sanitizeCenter(dataset.mapCenter),
|
29
29
|
zoom: parse(dataset.mapZoom),
|
30
30
|
menu: {
|
31
31
|
amendments: parse(dataset.menuAmendments),
|
@@ -55,12 +55,12 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
55
55
|
};
|
56
56
|
|
57
57
|
if (!window.localStorage) {
|
58
|
-
showMsg(window.DecidimAwesome.
|
58
|
+
showMsg(window.DecidimAwesome.i18n.autosavedError, true);
|
59
59
|
return;
|
60
60
|
}
|
61
61
|
|
62
62
|
if (window.localStorage.getItem(storeId)) {
|
63
|
-
showMsg(window.DecidimAwesome.
|
63
|
+
showMsg(window.DecidimAwesome.i18n.autosavedRetrieved, false, 5000);
|
64
64
|
}
|
65
65
|
|
66
66
|
// restore if available
|
@@ -85,7 +85,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
85
85
|
checkboxes[el.id] = el.checked;
|
86
86
|
});
|
87
87
|
window.localStorage.setItem(storeCheckboxesId, JSON.stringify(checkboxes));
|
88
|
-
showMsg(window.DecidimAwesome.
|
88
|
+
showMsg(window.DecidimAwesome.i18n.autosavedSuccess);
|
89
89
|
};
|
90
90
|
|
91
91
|
// save changes when modifications
|
@@ -2,53 +2,6 @@ import "formBuilder/dist/form-render.min.js";
|
|
2
2
|
import "src/decidim/decidim_awesome/forms/rich_text_plugin"
|
3
3
|
|
4
4
|
export default class CustomFieldsRenderer { // eslint-disable-line no-unused-vars
|
5
|
-
constructor() {
|
6
|
-
this.lang = this.getLang(window.DecidimAwesome.currentLocale);
|
7
|
-
}
|
8
|
-
|
9
|
-
getLang(lang) {
|
10
|
-
const langs = {
|
11
|
-
// ar: 'ar-SA', // Not in decidim yet
|
12
|
-
"ar": "ar-TN",
|
13
|
-
"ca": "ca-ES",
|
14
|
-
"cs": "cs-CZ",
|
15
|
-
"da": "da-DK",
|
16
|
-
"de": "de-DE",
|
17
|
-
"el": "el-GR",
|
18
|
-
"en": "en-US",
|
19
|
-
"es": "es-ES",
|
20
|
-
"fa": "fa-IR",
|
21
|
-
"fi": "fi-FI",
|
22
|
-
"fr": "fr-FR",
|
23
|
-
"he": "he-IL",
|
24
|
-
"hu": "hu-HU",
|
25
|
-
"it": "it-IT",
|
26
|
-
"ja": "ja-JP",
|
27
|
-
"my": "my-MM",
|
28
|
-
"nb": "nb-NO",
|
29
|
-
"nl": "nl-NL",
|
30
|
-
"pl": "pl-PL",
|
31
|
-
"pt": "pt-BR",
|
32
|
-
"qz": "qz-MM",
|
33
|
-
"ro": "ro-RO",
|
34
|
-
"ru": "ru-RU",
|
35
|
-
"sl": "sl-SI",
|
36
|
-
"th": "th-TH",
|
37
|
-
"tr": "tr-TR",
|
38
|
-
"uk": "uk-UA",
|
39
|
-
"vi": "vi-VN",
|
40
|
-
"zh-TW": "zh-TW",
|
41
|
-
"zh": "zh-CN"
|
42
|
-
};
|
43
|
-
if (langs[lang]) {
|
44
|
-
return langs[lang];
|
45
|
-
}
|
46
|
-
if (langs[lang.substr(0, 2)]) {
|
47
|
-
return langs[lang.substr(0, 2)];
|
48
|
-
}
|
49
|
-
return "en-US";
|
50
|
-
}
|
51
|
-
|
52
5
|
/*
|
53
6
|
* Creates an XML document with a subset of html-compatible dl/dd/dt elements
|
54
7
|
* to store the custom fields answers
|
@@ -116,70 +69,6 @@ export default class CustomFieldsRenderer { // eslint-disable-line no-unused-var
|
|
116
69
|
return `<xml>${$dl[0].outerHTML}</xml>`;
|
117
70
|
}
|
118
71
|
|
119
|
-
fixBuggyFields() {
|
120
|
-
if (!this.$element) {
|
121
|
-
return false;
|
122
|
-
}
|
123
|
-
|
124
|
-
/**
|
125
|
-
* Hack to fix required checkboxes being reset
|
126
|
-
* Issue: https://github.com/decidim-ice/decidim-module-decidim_awesome/issues/82
|
127
|
-
*/
|
128
|
-
this.$element.find(".formbuilder-checkbox-group").each((_key, group) => {
|
129
|
-
const inputs = $(".formbuilder-checkbox input", group);
|
130
|
-
const $label = $(group).find("label");
|
131
|
-
const data = this.spec.find((obj) => obj.type === "checkbox-group" && obj.name === $label.attr("for"));
|
132
|
-
let values = data.userData;
|
133
|
-
if (!inputs.length || !data || !values) {
|
134
|
-
return;
|
135
|
-
}
|
136
|
-
|
137
|
-
inputs.each((_idx, input) => {
|
138
|
-
let index = values.indexOf(input.value);
|
139
|
-
if (index >= 0) {
|
140
|
-
values.splice(index, 1)
|
141
|
-
// setting checked=true do not makes the browser aware that the form is valid if the field is required
|
142
|
-
if (!input.checked)
|
143
|
-
{$(input).click();}
|
144
|
-
} else if (input.checked)
|
145
|
-
{$(input).click();}
|
146
|
-
});
|
147
|
-
|
148
|
-
// Fill "other" option
|
149
|
-
const otherOption = $(".other-option", inputs.parent())[0];
|
150
|
-
const otherVal = $(".other-val", inputs.parent())[0];
|
151
|
-
const otherText = values.join(" ");
|
152
|
-
|
153
|
-
if (otherOption) {
|
154
|
-
if (otherText) {
|
155
|
-
otherOption.checked = true;
|
156
|
-
otherOption.value = otherText;
|
157
|
-
otherVal.value = otherText;
|
158
|
-
} else {
|
159
|
-
otherOption.checked = false;
|
160
|
-
otherOption.value = "";
|
161
|
-
otherVal.value = "";
|
162
|
-
}
|
163
|
-
}
|
164
|
-
});
|
165
|
-
|
166
|
-
/**
|
167
|
-
* Hack to fix required radio buttons "other" value
|
168
|
-
* Issue: https://github.com/decidim-ice/decidim-module-decidim_awesome/issues/133
|
169
|
-
*/
|
170
|
-
this.$element.find(".formbuilder-radio input.other-val").on("input", (input) => {
|
171
|
-
const $input = $(input.currentTarget);
|
172
|
-
const $group = $input.closest(".formbuilder-radio-group");
|
173
|
-
$group.find("input").each((_key, radio) => {
|
174
|
-
const name = $(radio).attr("name");
|
175
|
-
if (name && name.endsWith("[]")) {
|
176
|
-
$(radio).attr("name", name.slice(0, -2));
|
177
|
-
}
|
178
|
-
});
|
179
|
-
});
|
180
|
-
return this;
|
181
|
-
}
|
182
|
-
|
183
72
|
// Saves xml to the hidden input
|
184
73
|
storeData() {
|
185
74
|
if (!this.$element) {
|
@@ -203,7 +92,7 @@ export default class CustomFieldsRenderer { // eslint-disable-line no-unused-var
|
|
203
92
|
// in case of multilang tabs we only render one form due a limitation in the library for handling several instances
|
204
93
|
this.instance = $element.formRender({
|
205
94
|
i18n: {
|
206
|
-
locale:
|
95
|
+
locale: window.DecidimAwesome.currentLocale,
|
207
96
|
location: window.DecidimAwesome.formBuilderLangsLocation
|
208
97
|
},
|
209
98
|
formData: this.spec,
|
@@ -215,6 +104,5 @@ export default class CustomFieldsRenderer { // eslint-disable-line no-unused-var
|
|
215
104
|
}
|
216
105
|
}
|
217
106
|
});
|
218
|
-
this.fixBuggyFields();
|
219
107
|
}
|
220
108
|
}
|
@@ -15,7 +15,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
15
15
|
|
16
16
|
const span = document.createElement("span");
|
17
17
|
span.className = "input-character-counter__text";
|
18
|
-
span.innerHTML = window.DecidimAwesome.
|
18
|
+
span.innerHTML = window.DecidimAwesome.i18n.dragAndDropImage;
|
19
19
|
textarea.parentNode.appendChild(span);
|
20
20
|
attach(textarea, {
|
21
21
|
uploadUrl: window.DecidimAwesome.editorUploaderPath,
|