decidim-decidim_awesome 0.7.0 → 0.7.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +32 -9
- data/app/assets/config/decidim_admin_decidim_awesome_manifest.css +2 -2
- data/app/assets/config/decidim_admin_decidim_awesome_manifest.js +1 -2
- data/app/assets/config/decidim_decidim_awesome_manifest.css +2 -2
- data/app/assets/config/decidim_decidim_awesome_manifest.js +3 -2
- data/app/assets/config/legacy_decidim_admin_decidim_awesome_manifest.js +2 -0
- data/app/assets/config/legacy_decidim_decidim_awesome_manifest.js +4 -0
- data/app/assets/javascripts/decidim/decidim_awesome/admin/auto_edit.js.es6 +77 -0
- data/app/assets/javascripts/decidim/decidim_awesome/admin/codemirror.js.es6 +2 -3
- data/app/assets/javascripts/decidim/decidim_awesome/admin/form_builder.js.es6 +80 -0
- data/app/assets/javascripts/decidim/decidim_awesome/admin/legacy_form_builder.js.es6 +80 -0
- data/app/assets/javascripts/decidim/decidim_awesome/admin/user_picker.js.es6 +24 -0
- data/app/assets/javascripts/decidim/decidim_awesome/awesome_admin.js +7 -0
- data/app/assets/javascripts/decidim/decidim_awesome/{application.js → awesome_application.js} +1 -2
- data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/layers.js.es6 +3 -2
- data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/load_map.js.es6 +15 -0
- data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/map.js.es6 +52 -56
- data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/meetings.js.es6 +2 -2
- data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/proposals.js.es6 +1 -1
- data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/utilities.js.es6 +33 -24
- data/app/assets/javascripts/decidim/decidim_awesome/editors/legacy_quill_editor.js.es6 +14 -2
- data/app/assets/javascripts/decidim/decidim_awesome/editors/quill_editor.js.es6 +18 -4
- data/app/assets/javascripts/decidim/decidim_awesome/editors/tabs_focus.js.es6 +24 -0
- data/app/assets/javascripts/decidim/decidim_awesome/forms/custom_fields_builder.js.es6 +211 -0
- data/app/assets/javascripts/decidim/decidim_awesome/forms/rich_text_plugin.js.es6 +106 -0
- data/app/assets/javascripts/decidim/decidim_awesome/legacy_admin.js +5 -1
- data/app/assets/javascripts/decidim/decidim_awesome/legacy_application.js +0 -1
- data/app/assets/javascripts/decidim/decidim_awesome/proposals/custom_fields.js.es6 +21 -0
- data/app/assets/stylesheets/decidim/decidim_awesome/admin/auto_edits.scss +15 -0
- data/app/assets/stylesheets/decidim/decidim_awesome/admin/codemirror.scss +15 -4
- data/app/assets/stylesheets/decidim/decidim_awesome/admin/constraints.scss +12 -0
- data/app/assets/stylesheets/decidim/decidim_awesome/admin/custom_fields.scss +66 -0
- data/app/assets/stylesheets/decidim/decidim_awesome/admin/user_picker.scss +35 -0
- data/app/assets/stylesheets/decidim/decidim_awesome/{admin.scss → awesome_admin.scss} +12 -0
- data/app/assets/stylesheets/decidim/decidim_awesome/awesome_application.scss +22 -0
- data/app/assets/stylesheets/decidim/decidim_awesome/awesome_map/map.scss +0 -1
- data/app/assets/stylesheets/decidim/decidim_awesome/editors/quill_editor.scss +16 -1
- data/app/awesome_overrides/forms/decidim/proposals/proposal_wizard_create_step_form_override.rb +28 -0
- data/app/cells/decidim/decidim_awesome/content_blocks/map/show.erb +74 -0
- data/app/cells/decidim/decidim_awesome/content_blocks/map_cell.rb +54 -0
- data/app/cells/decidim/decidim_awesome/content_blocks/map_form/show.erb +61 -0
- data/app/cells/decidim/decidim_awesome/content_blocks/map_form_cell.rb +19 -0
- data/app/commands/concerns/decidim/decidim_awesome/admin/needs_constraint_helpers.rb +32 -0
- data/app/commands/decidim/decidim_awesome/admin/create_proposal_custom_field.rb +45 -0
- data/app/commands/decidim/decidim_awesome/admin/create_scoped_admin.rb +38 -0
- data/app/commands/decidim/decidim_awesome/admin/destroy_constraint.rb +4 -0
- data/app/commands/decidim/decidim_awesome/admin/destroy_proposal_custom_field.rb +40 -0
- data/app/commands/decidim/decidim_awesome/admin/destroy_scoped_admin.rb +40 -0
- data/app/commands/decidim/decidim_awesome/admin/destroy_scoped_style.rb +1 -1
- data/app/commands/decidim/decidim_awesome/admin/rename_scope_label.rb +58 -0
- data/app/commands/decidim/decidim_awesome/admin/update_config.rb +1 -0
- data/app/controllers/concerns/decidim/decidim_awesome/admin_not_found_redirect.rb +39 -0
- data/app/controllers/decidim/decidim_awesome/admin/config_controller.rb +31 -18
- data/app/controllers/decidim/decidim_awesome/admin/constraints_controller.rb +4 -0
- data/app/controllers/decidim/decidim_awesome/admin/proposal_custom_fields_controller.rb +38 -0
- data/app/controllers/decidim/decidim_awesome/admin/scoped_admins_controller.rb +38 -0
- data/app/controllers/decidim/decidim_awesome/admin/scoped_styles_controller.rb +38 -0
- data/app/forms/decidim/decidim_awesome/admin/config_form.rb +39 -0
- data/app/forms/decidim/decidim_awesome/admin/constraint_form.rb +3 -1
- data/app/helpers/decidim/decidim_awesome/admin/config_constraints_helpers.rb +11 -7
- data/app/helpers/decidim/decidim_awesome/amendments_helper_override.rb +48 -0
- data/app/helpers/decidim/decidim_awesome/map_helper.rb +67 -16
- data/app/helpers/decidim/decidim_awesome/proposals/application_helper_override.rb +78 -0
- data/app/middleware/decidim/decidim_awesome/current_config.rb +182 -0
- data/app/models/decidim/decidim_awesome/awesome_config.rb +15 -0
- data/app/models/decidim/decidim_awesome/user_override.rb +25 -0
- data/app/permissions/decidim/decidim_awesome/admin/permissions.rb +2 -0
- data/app/views/decidim/decidim_awesome/admin/checks/index.html.erb +1 -1
- data/app/views/decidim/decidim_awesome/admin/config/_autoedit_box_label.html.erb +7 -0
- data/app/views/decidim/decidim_awesome/admin/config/_constraints.html.erb +2 -2
- data/app/views/decidim/decidim_awesome/admin/config/_form_admins.html.erb +21 -0
- data/app/views/decidim/decidim_awesome/admin/config/_form_editors.html.erb +0 -3
- data/app/views/decidim/decidim_awesome/admin/config/_form_proposal_custom_fields.html.erb +25 -0
- data/app/views/decidim/decidim_awesome/admin/config/_form_proposals.html.erb +0 -2
- data/app/views/decidim/decidim_awesome/admin/config/_form_styles.html.erb +4 -7
- data/app/views/decidim/decidim_awesome/admin/proposals/_editor.html.erb +4 -0
- data/app/views/decidim/decidim_awesome/custom_fields/_form_render.html.erb +6 -0
- data/app/views/decidim/decidim_awesome/map_component/map/show.html.erb +0 -2
- data/app/views/decidim/proposals/admin/proposals/_form.html.erb +101 -0
- data/app/views/decidim/proposals/collaborative_drafts/_edit_form_fields.html.erb +83 -0
- data/app/views/decidim/proposals/collaborative_drafts/show.html.erb +1 -0
- data/app/views/layouts/decidim/admin/decidim_awesome.html.erb +25 -11
- data/app/views/layouts/decidim/decidim_awesome/_awesome_config.html.erb +4 -0
- data/app/views/layouts/decidim/decidim_awesome/_custom_styles.html.erb +1 -1
- data/app/views/v0.23/decidim/proposals/collaborative_drafts/_show.html.erb +134 -0
- data/app/views/v0.23/layouts/decidim/_head.html.erb +1 -1
- data/app/views/v0.23/layouts/decidim/admin/_header.html.erb +1 -1
- data/app/views/v0.24/decidim/proposals/collaborative_drafts/_show.html.erb +128 -0
- data/app/views/v0.24/layouts/decidim/_head.html.erb +2 -2
- data/app/views/v0.24/layouts/decidim/admin/_header.html.erb +2 -2
- data/config/locales/ca.yml +62 -3
- data/config/locales/cs.yml +62 -3
- data/config/locales/en.yml +90 -11
- data/config/locales/es.yml +61 -2
- data/config/locales/eu.yml +63 -4
- data/config/locales/fr.yml +62 -3
- data/config/locales/it.yml +284 -0
- data/config/locales/ja.yml +284 -0
- data/config/locales/nl.yml +62 -3
- data/config/locales/sv.yml +62 -3
- data/db/migrate/20210628150825_change_awesome_config_var_type.rb +12 -0
- data/lib/decidim/decidim_awesome/admin_engine.rb +16 -4
- data/lib/decidim/decidim_awesome/awesome_helpers.rb +17 -10
- data/lib/decidim/decidim_awesome/checksums.yml +17 -4
- data/lib/decidim/decidim_awesome/config.rb +53 -6
- data/lib/decidim/decidim_awesome/context_analyzers/request_analyzer.rb +27 -21
- data/lib/decidim/decidim_awesome/custom_fields.rb +94 -0
- data/lib/decidim/decidim_awesome/engine.rb +62 -6
- data/lib/decidim/decidim_awesome/test/shared_examples/box_label_editor.rb +116 -0
- data/lib/decidim/decidim_awesome/test/shared_examples/current_config_examples.rb +143 -0
- data/lib/decidim/decidim_awesome/test/shared_examples/editor_examples.rb +4 -0
- data/lib/decidim/decidim_awesome/test/shared_examples/scoped_admins_examples.rb +428 -0
- data/lib/decidim/decidim_awesome/version.rb +1 -1
- data/lib/decidim/decidim_awesome.rb +41 -8
- data/vendor/assets/javascripts/delta.min.js +405 -0
- data/vendor/assets/javascripts/delta.min.js.map +1 -0
- data/vendor/assets/javascripts/europa.min.js +4 -0
- data/vendor/assets/javascripts/form-builder.min.js +19 -0
- data/vendor/assets/javascripts/form-render.min.js +19 -0
- data/vendor/assets/javascripts/inscrybmde.min.js +1 -1
- data/vendor/assets/javascripts/jquery-ui.min.js +13 -0
- data/vendor/assets/javascripts/select2.js +6147 -0
- data/vendor/assets/langs/en-US.lang +110 -0
- data/vendor/assets/stylesheets/inscrybmde.min.scss +14 -0
- data/vendor/assets/stylesheets/jquery-ui.min.css +7 -0
- data/vendor/assets/stylesheets/select2-foundation-theme.css +249 -0
- data/vendor/assets/stylesheets/select2.css +515 -0
- metadata +68 -27
- data/app/assets/images/decidim/decidim_awesome/loading.gif +0 -0
- data/app/assets/javascripts/decidim/decidim_awesome/admin.js +0 -3
- data/app/assets/javascripts/decidim/decidim_awesome/editors/markdown_view.js.es6 +0 -12
- data/app/assets/stylesheets/decidim/decidim_awesome/application.scss +0 -8
- data/app/assets/stylesheets/decidim/decidim_awesome/editors/markdown_view.scss +0 -27
- data/app/awesome_overrides/presenters/decidim/proposals/proposal_presenter_override.rb +0 -58
- data/lib/decidim/decidim_awesome/content_renderers/markdown_renderer.rb +0 -18
- data/lib/decidim/decidim_awesome/content_renderers.rb +0 -9
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module DecidimAwesome
|
5
|
+
module Admin
|
6
|
+
class RenameScopeLabel < Rectify::Command
|
7
|
+
# Public: Initializes the command.
|
8
|
+
#
|
9
|
+
# params - A constraint params
|
10
|
+
def initialize(params, organization)
|
11
|
+
@text = params[:text]&.strip&.gsub(" ", "_")&.parameterize&.truncate(64)
|
12
|
+
@scope = params[:scope]
|
13
|
+
@key = params[:key]
|
14
|
+
@attribute = params[:attribute]
|
15
|
+
@organization = organization
|
16
|
+
end
|
17
|
+
|
18
|
+
# Executes the command. Broadcasts these events:
|
19
|
+
#
|
20
|
+
# - :ok when everything is valid.
|
21
|
+
# - :invalid if we couldn't proceed.
|
22
|
+
#
|
23
|
+
# Returns nothing.
|
24
|
+
def call
|
25
|
+
raise StandardError, "empty value" if @text.blank?
|
26
|
+
raise StandardError, "key already exists" if config.value.keys.include? @text
|
27
|
+
|
28
|
+
transaction do
|
29
|
+
config.value[@text] = config.value.delete @key
|
30
|
+
config.save!
|
31
|
+
if config_scope
|
32
|
+
config_scope.var = scope
|
33
|
+
config_scope.save!
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
broadcast(:ok, { scope: scope, key: @text })
|
38
|
+
rescue StandardError => e
|
39
|
+
broadcast(:invalid, e.message)
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def scope
|
45
|
+
@scope.gsub(/_#{@key}$/, "_#{@text}")
|
46
|
+
end
|
47
|
+
|
48
|
+
def config
|
49
|
+
@config ||= Decidim::DecidimAwesome::AwesomeConfig.find_by!(var: @attribute, organization: @organization)
|
50
|
+
end
|
51
|
+
|
52
|
+
def config_scope
|
53
|
+
@config_scope ||= Decidim::DecidimAwesome::AwesomeConfig.find_by(var: @scope, organization: @organization)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -20,6 +20,7 @@ module Decidim
|
|
20
20
|
def call
|
21
21
|
if form.invalid?
|
22
22
|
message = form.errors[:scoped_styles].join("; ") if @form.errors[:scoped_styles].any?
|
23
|
+
message = form.errors[:scoped_admins].join("; ") if @form.errors[:scoped_admins].any?
|
23
24
|
return broadcast(:invalid, message, form.errors)
|
24
25
|
end
|
25
26
|
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module DecidimAwesome
|
5
|
+
module AdminNotFoundRedirect
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
# rubocop:disable Rails/LexicallyScopedActionFilter:
|
10
|
+
before_action :redirect_unallowed_scoped_admins, only: :not_found
|
11
|
+
# rubocop:enable Rails/LexicallyScopedActionFilter
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def redirect_unallowed_scoped_admins
|
16
|
+
return unless request.original_fullpath =~ %r{^(/+)admin}
|
17
|
+
return unless Decidim::User.respond_to? :awesome_potential_admins
|
18
|
+
return unless defined? current_user
|
19
|
+
return unless Decidim::User.awesome_potential_admins.include? current_user.id
|
20
|
+
|
21
|
+
# assiging a flash message here does not work after redirection due the order of middleware in Rails
|
22
|
+
# as a workaround, send a message through a get parameter
|
23
|
+
path = "/admin/?unauthorized"
|
24
|
+
referer = request.headers["Referer"]
|
25
|
+
if referer
|
26
|
+
uri = URI(referer)
|
27
|
+
params = Rack::Utils.parse_query uri.query
|
28
|
+
unless request.params.has_key? "unauthorized"
|
29
|
+
params["unauthorized"] = nil
|
30
|
+
path = "#{uri.path}?#{Rack::Utils.build_query(params)}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
redirect_to path
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -11,7 +11,7 @@ module Decidim
|
|
11
11
|
|
12
12
|
layout "decidim/admin/decidim_awesome"
|
13
13
|
|
14
|
-
helper_method :constraints_for
|
14
|
+
helper_method :constraints_for, :users_for
|
15
15
|
before_action do
|
16
16
|
enforce_permission_to :edit_config, configs
|
17
17
|
end
|
@@ -35,32 +35,37 @@ module Decidim
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
-
def
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
38
|
+
def users
|
39
|
+
respond_to do |format|
|
40
|
+
format.json do
|
41
|
+
if (term = params[:term].to_s).present?
|
42
|
+
query = current_organization.users.order(name: :asc)
|
43
|
+
query = query.where("name ILIKE :term OR nickname ILIKE :term OR email ILIKE :term", term: "%#{term}%")
|
44
|
+
|
45
|
+
render json: query.all.collect { |u| { id: u.id, text: format_user_name(u) } }
|
46
|
+
else
|
47
|
+
render json: []
|
48
|
+
end
|
46
49
|
end
|
47
50
|
end
|
48
|
-
|
49
|
-
redirect_to decidim_admin_decidim_awesome.config_path(:styles)
|
50
51
|
end
|
51
52
|
|
52
|
-
def
|
53
|
-
|
54
|
-
on(:ok) do |
|
55
|
-
|
53
|
+
def rename_scope_label
|
54
|
+
RenameScopeLabel.call(params, current_organization) do
|
55
|
+
on(:ok) do |result|
|
56
|
+
render json: result.merge({
|
57
|
+
html: render_to_string(partial: "decidim/decidim_awesome/admin/config/constraints",
|
58
|
+
locals: {
|
59
|
+
key: result[:scope],
|
60
|
+
constraints: constraints_for(result[:scope])
|
61
|
+
})
|
62
|
+
})
|
56
63
|
end
|
57
64
|
|
58
65
|
on(:invalid) do |message|
|
59
|
-
|
66
|
+
render json: { error: message }, status: :unprocessable_entity
|
60
67
|
end
|
61
68
|
end
|
62
|
-
|
63
|
-
redirect_to decidim_admin_decidim_awesome.config_path(:styles)
|
64
69
|
end
|
65
70
|
|
66
71
|
private
|
@@ -74,6 +79,14 @@ module Decidim
|
|
74
79
|
|
75
80
|
DecidimAwesome.config.keys
|
76
81
|
end
|
82
|
+
|
83
|
+
def users_for(ids_list)
|
84
|
+
Decidim::User.where(id: ids_list).map { |user| OpenStruct.new(text: format_user_name(user), id: user.id) }
|
85
|
+
end
|
86
|
+
|
87
|
+
def format_user_name(user)
|
88
|
+
"<span class='#{"is-admin" if user.read_attribute("admin")}'>#{user.name} (@#{user.nickname} - #{user.email})</span>"
|
89
|
+
end
|
77
90
|
end
|
78
91
|
end
|
79
92
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module DecidimAwesome
|
5
|
+
module Admin
|
6
|
+
# Global configuration controller
|
7
|
+
class ProposalCustomFieldsController < DecidimAwesome::Admin::ConfigController
|
8
|
+
def create
|
9
|
+
CreateProposalCustomField.call(current_organization) do
|
10
|
+
on(:ok) do |key|
|
11
|
+
flash[:notice] = I18n.t("config.create_proposal_custom_field.success", key: key, scope: "decidim.decidim_awesome.admin")
|
12
|
+
end
|
13
|
+
|
14
|
+
on(:invalid) do |message|
|
15
|
+
flash[:alert] = I18n.t("config.create_proposal_custom_field.error", error: message, scope: "decidim.decidim_awesome.admin")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
redirect_to decidim_admin_decidim_awesome.config_path(:proposal_custom_fields)
|
20
|
+
end
|
21
|
+
|
22
|
+
def destroy
|
23
|
+
DestroyProposalCustomField.call(params[:key], current_organization) do
|
24
|
+
on(:ok) do |key|
|
25
|
+
flash[:notice] = I18n.t("config.destroy_proposal_custom_field.success", key: key, scope: "decidim.decidim_awesome.admin")
|
26
|
+
end
|
27
|
+
|
28
|
+
on(:invalid) do |message|
|
29
|
+
flash[:alert] = I18n.t("config.destroy_proposal_custom_field.error", error: message, scope: "decidim.decidim_awesome.admin")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
redirect_to decidim_admin_decidim_awesome.config_path(:proposal_custom_fields)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module DecidimAwesome
|
5
|
+
module Admin
|
6
|
+
# Global configuration controller
|
7
|
+
class ScopedAdminsController < DecidimAwesome::Admin::ConfigController
|
8
|
+
def create
|
9
|
+
CreateScopedAdmin.call(current_organization) do
|
10
|
+
on(:ok) do |key|
|
11
|
+
flash[:notice] = I18n.t("config.create_scoped_admin.success", key: key, scope: "decidim.decidim_awesome.admin")
|
12
|
+
end
|
13
|
+
|
14
|
+
on(:invalid) do |message|
|
15
|
+
flash[:alert] = I18n.t("config.create_scoped_admin.error", error: message, scope: "decidim.decidim_awesome.admin")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
redirect_to decidim_admin_decidim_awesome.config_path(:admins)
|
20
|
+
end
|
21
|
+
|
22
|
+
def destroy
|
23
|
+
DestroyScopedAdmin.call(params[:key], current_organization) do
|
24
|
+
on(:ok) do |key|
|
25
|
+
flash[:notice] = I18n.t("config.destroy_scoped_admin.success", key: key, scope: "decidim.decidim_awesome.admin")
|
26
|
+
end
|
27
|
+
|
28
|
+
on(:invalid) do |message|
|
29
|
+
flash[:alert] = I18n.t("config.destroy_scoped_admin.error", error: message, scope: "decidim.decidim_awesome.admin")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
redirect_to decidim_admin_decidim_awesome.config_path(:admins)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module DecidimAwesome
|
5
|
+
module Admin
|
6
|
+
# Global configuration controller
|
7
|
+
class ScopedStylesController < DecidimAwesome::Admin::ConfigController
|
8
|
+
def create
|
9
|
+
CreateScopedStyle.call(current_organization) do
|
10
|
+
on(:ok) do |key|
|
11
|
+
flash[:notice] = I18n.t("config.create_scoped_style.success", key: key, scope: "decidim.decidim_awesome.admin")
|
12
|
+
end
|
13
|
+
|
14
|
+
on(:invalid) do |message|
|
15
|
+
flash[:alert] = I18n.t("config.create_scoped_style.error", error: message, scope: "decidim.decidim_awesome.admin")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
redirect_to decidim_admin_decidim_awesome.config_path(:styles)
|
20
|
+
end
|
21
|
+
|
22
|
+
def destroy
|
23
|
+
DestroyScopedStyle.call(params[:key], current_organization) do
|
24
|
+
on(:ok) do |key|
|
25
|
+
flash[:notice] = I18n.t("config.destroy_scoped_style.success", key: key, scope: "decidim.decidim_awesome.admin")
|
26
|
+
end
|
27
|
+
|
28
|
+
on(:invalid) do |message|
|
29
|
+
flash[:alert] = I18n.t("config.destroy_scoped_style.error", error: message, scope: "decidim.decidim_awesome.admin")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
redirect_to decidim_admin_decidim_awesome.config_path(:styles)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -4,6 +4,8 @@ module Decidim
|
|
4
4
|
module DecidimAwesome
|
5
5
|
module Admin
|
6
6
|
class ConfigForm < Decidim::Form
|
7
|
+
include ActionView::Helpers::SanitizeHelper
|
8
|
+
|
7
9
|
attribute :allow_images_in_full_editor, Boolean
|
8
10
|
attribute :allow_images_in_small_editor, Boolean
|
9
11
|
attribute :allow_images_in_proposals, Boolean
|
@@ -11,6 +13,8 @@ module Decidim
|
|
11
13
|
attribute :allow_images_in_markdown_editor, Boolean
|
12
14
|
attribute :auto_save_forms, Boolean
|
13
15
|
attribute :scoped_styles, Hash
|
16
|
+
attribute :proposal_custom_fields, Hash
|
17
|
+
attribute :scoped_admins, Hash
|
14
18
|
attribute :menu, Array[MenuForm]
|
15
19
|
attribute :intergram_for_admins, Boolean
|
16
20
|
attribute :intergram_for_admins_settings, IntergramForm
|
@@ -21,21 +25,56 @@ module Decidim
|
|
21
25
|
attr_accessor :valid_keys
|
22
26
|
|
23
27
|
validate :css_syntax, if: ->(form) { form.scoped_styles.present? }
|
28
|
+
validate :json_syntax, if: ->(form) { form.proposal_custom_fields.present? }
|
29
|
+
|
30
|
+
# TODO: validate non general admins are here
|
24
31
|
|
25
32
|
def self.from_params(params, additional_params = {})
|
26
33
|
instance = super(params, additional_params)
|
27
34
|
instance.valid_keys = params.keys.map(&:to_sym) || []
|
35
|
+
instance.sanitize_labels!
|
28
36
|
instance
|
29
37
|
end
|
30
38
|
|
31
39
|
def css_syntax
|
32
40
|
scoped_styles.each do |key, code|
|
41
|
+
next unless code
|
42
|
+
|
33
43
|
SassC::Engine.new(code).render
|
34
44
|
rescue SassC::SyntaxError => e
|
35
45
|
errors.add(:scoped_styles, I18n.t("config.form.errors.incorrect_css", key: key, scope: "decidim.decidim_awesome.admin"))
|
36
46
|
errors.add(key.to_sym, e.message)
|
37
47
|
end
|
38
48
|
end
|
49
|
+
|
50
|
+
def json_syntax
|
51
|
+
proposal_custom_fields.each do |key, code|
|
52
|
+
next unless code
|
53
|
+
|
54
|
+
JSON.parse(code)
|
55
|
+
rescue JSON::ParserError => e
|
56
|
+
errors.add(:scoped_styles, I18n.t("config.form.errors.incorrect_json", key: key, scope: "decidim.decidim_awesome.admin"))
|
57
|
+
errors.add(key.to_sym, e.message)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# formBuilder has a bug and do not sanitize text if users copy/paste text with format in the label input
|
62
|
+
def sanitize_labels!
|
63
|
+
return unless proposal_custom_fields
|
64
|
+
|
65
|
+
proposal_custom_fields.transform_values! do |code|
|
66
|
+
next unless code
|
67
|
+
|
68
|
+
json = JSON.parse(code)
|
69
|
+
json.map! do |item|
|
70
|
+
item["label"] = strip_tags(item["label"])
|
71
|
+
item
|
72
|
+
end
|
73
|
+
JSON.generate(json)
|
74
|
+
rescue JSON::ParserError
|
75
|
+
code
|
76
|
+
end
|
77
|
+
end
|
39
78
|
end
|
40
79
|
end
|
41
80
|
end
|
@@ -10,7 +10,9 @@ module Decidim
|
|
10
10
|
attribute :component_manifest, String
|
11
11
|
attribute :component_id, Integer
|
12
12
|
|
13
|
-
validates :component_manifest, absence: true, if:
|
13
|
+
validates :component_manifest, absence: true, if: lambda { |form|
|
14
|
+
form.component_id.present? || ConfigConstraintsHelpers::OTHER_MANIFESTS.include?(form.participatory_space_manifest&.to_sym)
|
15
|
+
}
|
14
16
|
validates :component_id, absence: true, if: ->(form) { form.component_manifest.present? }
|
15
17
|
end
|
16
18
|
end
|
@@ -4,6 +4,8 @@ module Decidim
|
|
4
4
|
module DecidimAwesome
|
5
5
|
module Admin
|
6
6
|
module ConfigConstraintsHelpers
|
7
|
+
OTHER_MANIFESTS = [:none, :system, :process_groups].freeze
|
8
|
+
|
7
9
|
include Decidim::TranslatableAttributes
|
8
10
|
|
9
11
|
def check(status)
|
@@ -28,7 +30,7 @@ module Decidim
|
|
28
30
|
end
|
29
31
|
|
30
32
|
def participatory_space_manifests
|
31
|
-
manifests = {
|
33
|
+
manifests = OTHER_MANIFESTS.map { |m| [m, I18n.t("decidim.decidim_awesome.admin.config.#{m}")] }.to_h
|
32
34
|
Decidim.participatory_space_manifests.pluck(:name).each do |name|
|
33
35
|
manifests[name.to_sym] = I18n.t("decidim.admin.menu.#{name}")
|
34
36
|
end
|
@@ -36,7 +38,7 @@ module Decidim
|
|
36
38
|
end
|
37
39
|
|
38
40
|
def component_manifests(space = nil)
|
39
|
-
return {} if space
|
41
|
+
return {} if OTHER_MANIFESTS.include?(space)
|
40
42
|
|
41
43
|
Decidim.component_manifests.pluck(:name).map do |name|
|
42
44
|
[name.to_sym, I18n.t("decidim.components.#{name}.name")]
|
@@ -44,17 +46,17 @@ module Decidim
|
|
44
46
|
end
|
45
47
|
|
46
48
|
def participatory_spaces_list(manifest)
|
47
|
-
space =
|
49
|
+
space = model_for_manifest(manifest)
|
48
50
|
return {} if space.blank?
|
49
51
|
|
50
52
|
space.where(organization: current_organization).map do |item|
|
51
|
-
[item.slug, translated_attribute(item.title)]
|
53
|
+
[item.try(:slug) || item.id.to_s, translated_attribute(item.title)]
|
52
54
|
end.to_h
|
53
55
|
end
|
54
56
|
|
55
57
|
def components_list(manifest, slug)
|
56
|
-
space =
|
57
|
-
return {}
|
58
|
+
space = model_for_manifest(manifest)
|
59
|
+
return {} unless space&.column_names&.include? "slug"
|
58
60
|
|
59
61
|
components = Component.where(participatory_space: space.find_by(slug: slug))
|
60
62
|
components.map do |item|
|
@@ -84,9 +86,11 @@ module Decidim
|
|
84
86
|
|
85
87
|
private
|
86
88
|
|
87
|
-
def
|
89
|
+
def model_for_manifest(manifest)
|
88
90
|
return nil if manifest.blank?
|
89
91
|
|
92
|
+
return Decidim::ParticipatoryProcessGroup if manifest == "process_groups"
|
93
|
+
|
90
94
|
space = Decidim.find_participatory_space_manifest(manifest)
|
91
95
|
return nil unless space
|
92
96
|
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module DecidimAwesome
|
5
|
+
module AmendmentsHelperOverride
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
# original method
|
10
|
+
alias_method :decidim_amendments_form_field_for, :amendments_form_field_for
|
11
|
+
|
12
|
+
# override with custom fields if scope applies
|
13
|
+
def amendments_form_field_for(attribute, form, original_resource)
|
14
|
+
custom_fields = awesome_custom_fields(attribute, form)
|
15
|
+
return decidim_amendments_form_field_for(attribute, form, original_resource) if custom_fields.blank?
|
16
|
+
|
17
|
+
render_amendment_custom_fields_override(custom_fields, attribute, form, original_resource)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def render_amendment_custom_fields_override(fields, attribute, form, original_resource)
|
23
|
+
custom_fields = Decidim::DecidimAwesome::CustomFields.new(fields)
|
24
|
+
custom_fields.translate!
|
25
|
+
body = amendments_form_fields_value(original_resource, attribute)
|
26
|
+
custom_fields.apply_xml(body) if body.present?
|
27
|
+
# TODO: find a way to add errors as form is not the parent form
|
28
|
+
# form.object.errors.add(attribute, custom_fields.errors) if custom_fields.errors
|
29
|
+
render partial: "decidim/decidim_awesome/custom_fields/form_render", locals: { spec: custom_fields.to_json, form: form, name: attribute }
|
30
|
+
end
|
31
|
+
|
32
|
+
# Amendments don't use a URL specifying participatory space and component
|
33
|
+
# context for awesome config constraints must be obtained from the resource
|
34
|
+
def awesome_custom_fields(attribute, _form)
|
35
|
+
return unless attribute == :body
|
36
|
+
|
37
|
+
component = amendable.try(:component)
|
38
|
+
return unless component
|
39
|
+
return if component.settings.participatory_texts_enabled?
|
40
|
+
|
41
|
+
awesome_config = Decidim::DecidimAwesome::Config.new(component.organization)
|
42
|
+
awesome_config.context_from_component(component)
|
43
|
+
awesome_config.collect_sub_configs_values("proposal_custom_field")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -5,11 +5,19 @@ module Decidim
|
|
5
5
|
module MapHelper
|
6
6
|
include Decidim::MapHelper
|
7
7
|
|
8
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
9
|
+
# rubocop:disable Metrics/PerceivedComplexity:
|
8
10
|
def awesome_map_for(components, &block)
|
9
|
-
|
10
|
-
return unless map
|
11
|
+
return unless map_utility_dynamic
|
11
12
|
|
12
|
-
|
13
|
+
map = awesome_builder.map_element({ class: "google-map" }, &block)
|
14
|
+
help = content_tag(:div, class: "map__help") do
|
15
|
+
sr_content = content_tag(:p, t("screen_reader_explanation", scope: "decidim.map.dynamic"), class: "show-for-sr")
|
16
|
+
|
17
|
+
sr_content
|
18
|
+
end
|
19
|
+
|
20
|
+
html_options = {
|
13
21
|
"class" => "awesome-map",
|
14
22
|
"id" => "awesome-map",
|
15
23
|
"data-components" => components.map do |component|
|
@@ -21,20 +29,40 @@ module Decidim
|
|
21
29
|
amendments: component.manifest.name == :proposals ? Decidim::Proposals::Proposal.where(component: component).only_emendations.count : 0
|
22
30
|
}
|
23
31
|
end.to_json,
|
24
|
-
"data-
|
25
|
-
"data-
|
26
|
-
"data-
|
27
|
-
"data-map-
|
28
|
-
"data-
|
29
|
-
"data-menu-
|
30
|
-
"data-menu-
|
31
|
-
"data-
|
32
|
-
"data-show-
|
33
|
-
"data-show-
|
34
|
-
"data-show-
|
35
|
-
"data-show-
|
32
|
+
"data-hide-controls" => settings_source.try(:hide_controls),
|
33
|
+
"data-collapsed" => global_settings.collapse,
|
34
|
+
"data-truncate" => global_settings.truncate || 255,
|
35
|
+
"data-map-center" => global_settings.map_center,
|
36
|
+
"data-map-zoom" => global_settings.map_zoom || 8,
|
37
|
+
"data-menu-amendments" => global_settings.menu_amendments,
|
38
|
+
"data-menu-meetings" => global_settings.menu_meetings,
|
39
|
+
"data-menu-hashtags" => global_settings.menu_hashtags,
|
40
|
+
"data-show-not-answered" => step_settings&.show_not_answered,
|
41
|
+
"data-show-accepted" => step_settings&.show_accepted,
|
42
|
+
"data-show-withdrawn" => step_settings&.show_withdrawn,
|
43
|
+
"data-show-evaluating" => step_settings&.show_evaluating,
|
44
|
+
"data-show-rejected" => step_settings&.show_rejected
|
36
45
|
}
|
37
|
-
|
46
|
+
|
47
|
+
content_tag(:div, html_options) do
|
48
|
+
content_tag :div, class: "row column" do
|
49
|
+
help + map
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
54
|
+
# rubocop:enable Metrics/PerceivedComplexity:
|
55
|
+
|
56
|
+
def step_settings
|
57
|
+
settings_source.try(:current_settings)
|
58
|
+
end
|
59
|
+
|
60
|
+
def global_settings
|
61
|
+
settings_source.try(:settings)
|
62
|
+
end
|
63
|
+
|
64
|
+
def settings_source
|
65
|
+
try(:current_component) || self
|
38
66
|
end
|
39
67
|
|
40
68
|
# rubocop:disable Rails/HelperInstanceVariable
|
@@ -56,6 +84,29 @@ module Decidim
|
|
56
84
|
|
57
85
|
private
|
58
86
|
|
87
|
+
def awesome_builder
|
88
|
+
options = {
|
89
|
+
popup_template_id: "marker-popup",
|
90
|
+
markers: []
|
91
|
+
}
|
92
|
+
builder = map_utility_dynamic.create_builder(self, options)
|
93
|
+
|
94
|
+
unless snippets.any?(:map)
|
95
|
+
snippets.add(:map, builder.stylesheet_snippets)
|
96
|
+
snippets.add(:map, builder.javascript_snippets)
|
97
|
+
snippets.add(:head, snippets.for(:map))
|
98
|
+
end
|
99
|
+
|
100
|
+
unless snippets.any?(:awesome_map)
|
101
|
+
snippets.add(:awesome_map, stylesheet_link_tag("decidim/decidim_awesome/awesome_map/map"))
|
102
|
+
snippets.add(:awesome_map, javascript_include_tag("decidim/decidim_awesome/awesome_map/map"))
|
103
|
+
snippets.add(:awesome_map, javascript_include_tag("decidim/decidim_awesome/awesome_map/load_map"))
|
104
|
+
snippets.add(:head, snippets.for(:awesome_map))
|
105
|
+
end
|
106
|
+
|
107
|
+
builder
|
108
|
+
end
|
109
|
+
|
59
110
|
# rubocop:disable Style/FormatStringToken
|
60
111
|
def append_category(category)
|
61
112
|
@h += @golden_ratio_conjugate
|