decidim-decidim_awesome 0.8.3 → 0.9.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of decidim-decidim_awesome might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +32 -0
- data/README.md +54 -45
- data/Rakefile +1 -1
- data/app/commands/decidim/decidim_awesome/admin/create_constraint.rb +1 -1
- data/app/commands/decidim/decidim_awesome/admin/create_custom_redirect.rb +1 -1
- data/app/commands/decidim/decidim_awesome/admin/create_menu_hack.rb +1 -1
- data/app/commands/decidim/decidim_awesome/admin/create_proposal_custom_field.rb +1 -1
- data/app/commands/decidim/decidim_awesome/admin/create_scoped_admin.rb +1 -1
- data/app/commands/decidim/decidim_awesome/admin/create_scoped_style.rb +1 -1
- data/app/commands/decidim/decidim_awesome/admin/destroy_constraint.rb +1 -1
- data/app/commands/decidim/decidim_awesome/admin/destroy_custom_redirect.rb +1 -1
- data/app/commands/decidim/decidim_awesome/admin/destroy_menu_hack.rb +1 -1
- data/app/commands/decidim/decidim_awesome/admin/destroy_proposal_custom_field.rb +1 -1
- data/app/commands/decidim/decidim_awesome/admin/destroy_scoped_admin.rb +1 -1
- data/app/commands/decidim/decidim_awesome/admin/destroy_scoped_style.rb +1 -1
- data/app/commands/decidim/decidim_awesome/admin/rename_scope_label.rb +1 -1
- data/app/commands/decidim/decidim_awesome/admin/update_config.rb +2 -3
- data/app/commands/decidim/decidim_awesome/admin/update_constraint.rb +2 -2
- data/app/commands/decidim/decidim_awesome/admin/update_custom_redirect.rb +1 -1
- data/app/commands/decidim/decidim_awesome/admin/update_menu_hack.rb +1 -1
- data/app/commands/decidim/decidim_awesome/command.rb +14 -0
- data/app/commands/decidim/decidim_awesome/create_editor_image.rb +1 -1
- data/app/controllers/concerns/decidim/decidim_awesome/admin_accountability/admin/filterable.rb +67 -0
- data/app/controllers/concerns/decidim/decidim_awesome/admin_accountability/admin/filterable_helper.rb +37 -0
- data/app/controllers/decidim/decidim_awesome/admin/admin_accountability_controller.rb +51 -0
- data/app/controllers/decidim/decidim_awesome/admin/checks_controller.rb +6 -3
- data/app/controllers/decidim/decidim_awesome/admin/config_controller.rb +2 -0
- data/app/controllers/decidim/decidim_awesome/admin/custom_redirects_controller.rb +2 -0
- data/app/controllers/decidim/decidim_awesome/admin/menu_hacks_controller.rb +2 -0
- data/app/controllers/decidim/decidim_awesome/editor_images_controller.rb +0 -2
- data/app/forms/decidim/decidim_awesome/admin/config_form.rb +14 -0
- data/app/forms/decidim/decidim_awesome/admin/menu_form.rb +1 -1
- data/app/forms/decidim/decidim_awesome/proposals/proposal_wizard_create_step_form_override.rb +26 -8
- data/app/helpers/decidim/decidim_awesome/admin/config_constraints_helpers.rb +12 -8
- data/app/helpers/decidim/decidim_awesome/map_helper.rb +14 -11
- data/app/jobs/decidim/decidim_awesome/export_admin_actions_job.rb +28 -0
- data/app/middleware/decidim/decidim_awesome/current_config.rb +4 -0
- data/app/models/decidim/decidim_awesome/awesome_config.rb +0 -1
- data/app/models/decidim/decidim_awesome/config_constraint.rb +0 -2
- data/app/models/decidim/decidim_awesome/editor_image.rb +0 -3
- data/app/models/decidim/decidim_awesome/paper_trail_version.rb +99 -0
- data/app/packs/entrypoints/decidim_admin_decidim_awesome.js +3 -2
- data/app/packs/images/decidim/decidim_awesome/pokecode-logo.png +0 -0
- data/app/packs/src/decidim/decidim_awesome/admin/auto_edit.js +7 -7
- data/app/packs/src/decidim/decidim_awesome/admin/check_redirections.js +2 -2
- data/app/packs/src/decidim/decidim_awesome/admin/constraints.js +5 -5
- data/app/packs/src/decidim/decidim_awesome/admin/custom_fields_builder.js +11 -10
- data/app/packs/src/decidim/decidim_awesome/admin/form_exit_warn.js +1 -0
- data/app/packs/src/decidim/decidim_awesome/admin/user_picker.js +1 -0
- data/app/packs/src/decidim/decidim_awesome/awesome_map/api/fetcher.js +13 -13
- data/app/packs/src/decidim/decidim_awesome/awesome_map/awesome_map.js +14 -12
- data/app/packs/src/decidim/decidim_awesome/awesome_map/controllers/controller.js +16 -12
- data/app/packs/src/decidim/decidim_awesome/awesome_map/controllers/proposals_controller.js +3 -3
- data/app/packs/src/decidim/decidim_awesome/awesome_map/controls_ui.js +25 -26
- data/app/packs/src/decidim/decidim_awesome/awesome_map/load_map.js +1 -0
- data/app/packs/src/decidim/decidim_awesome/editors/editor.js +33 -12
- data/app/packs/src/decidim/decidim_awesome/forms/autosave.js +8 -12
- data/app/packs/src/decidim/decidim_awesome/forms/custom_fields_renderer.js +36 -27
- data/app/packs/src/decidim/decidim_awesome/forms/rich_text_plugin.js +6 -4
- data/app/packs/src/decidim/decidim_awesome/proposals/custom_fields.js +7 -7
- data/app/packs/src/decidim/decidim_awesome/proposals/images.js +2 -2
- data/app/packs/stylesheets/decidim/decidim_awesome/awesome_admin.scss +8 -5
- data/app/permissions/decidim/decidim_awesome/admin/permissions.rb +15 -1
- data/app/permissions/decidim/decidim_awesome/permissions.rb +4 -6
- data/app/presenters/decidim/decidim_awesome/paper_trail_base_presenter.rb +28 -0
- data/app/presenters/decidim/decidim_awesome/participatory_space_role_presenter.rb +45 -0
- data/app/presenters/decidim/decidim_awesome/role_base_presenter.rb +102 -0
- data/app/presenters/decidim/decidim_awesome/user_entity_presenter.rb +50 -0
- data/app/serializers/decidim/decidim_awesome/paper_trail_version_serializer.rb +37 -0
- data/app/validators/concerns/decidim/decidim_awesome/etiquette_validator_override.rb +41 -0
- data/app/views/decidim/decidim_awesome/admin/admin_accountability/index.html.erb +59 -0
- data/app/views/decidim/decidim_awesome/admin/checks/_assets_tester.html.erb +2 -0
- data/app/views/decidim/decidim_awesome/admin/config/_form_proposals.html.erb +82 -2
- data/app/views/decidim/decidim_awesome/admin/shared/_filters_with_date.html.erb +56 -0
- data/app/views/decidim/proposals/admin/proposals/_form.html.erb +1 -1
- data/app/views/decidim/proposals/collaborative_drafts/_edit_form_fields.html.erb +9 -17
- data/app/views/layouts/decidim/admin/decidim_awesome.html.erb +1 -1
- data/app/views/{v0.25 → v0.27}/layouts/decidim/_head.html.erb +12 -4
- data/config/i18n-tasks.yml +4 -0
- data/config/locales/ca.yml +22 -2
- data/config/locales/cs.yml +7 -2
- data/config/locales/de.yml +20 -1
- data/config/locales/en.yml +90 -1
- data/config/locales/es.yml +2 -2
- data/config/locales/fr.yml +22 -2
- data/config/locales/it.yml +2 -2
- data/config/locales/ja.yml +3 -2
- data/config/locales/nl.yml +1 -1
- data/config/locales/pt-BR.yml +2 -2
- data/db/seeds.rb +1 -1
- data/lib/decidim/decidim_awesome/admin_engine.rb +15 -1
- data/lib/decidim/decidim_awesome/awesome.rb +55 -1
- data/lib/decidim/decidim_awesome/checksums.yml +13 -3
- data/lib/decidim/decidim_awesome/config.rb +14 -14
- data/lib/decidim/decidim_awesome/context_analyzers/request_analyzer.rb +1 -1
- data/lib/decidim/decidim_awesome/engine.rb +36 -9
- data/lib/decidim/decidim_awesome/iframe_component/component.rb +2 -1
- data/lib/decidim/decidim_awesome/menu_hacker.rb +6 -0
- data/lib/decidim/decidim_awesome/system_checker.rb +2 -0
- data/lib/decidim/decidim_awesome/test/factories.rb +7 -0
- data/lib/decidim/decidim_awesome/test/initializer.rb +10 -2
- data/lib/decidim/decidim_awesome/test/shared_examples/action_log_presenter_examples.rb +61 -0
- data/lib/decidim/decidim_awesome/test/shared_examples/scoped_admins_examples.rb +7 -4
- data/lib/decidim/decidim_awesome/test/shared_examples/summary_examples.rb +2 -2
- data/lib/decidim/decidim_awesome/version.rb +2 -2
- data/lib/tasks/decidim_awesome_active_storage_migrations_tasks.rake +1 -3
- data/package.json +21 -164
- metadata +39 -39
- data/app/packs/images/decidim/decidim_awesome/platoniq-logo.png +0 -0
- data/app/packs/src/vendor/image-resize.min.js +0 -1
- data/app/packs/src/vendor/image-upload.min.js +0 -6
- data/app/packs/src/vendor/leaflet.featuregroup.subgroup.js +0 -184
- /data/app/views/{v0.25 → v0.27}/decidim/proposals/collaborative_drafts/_show.html.erb +0 -0
- /data/app/views/{v0.25 → v0.27}/layouts/decidim/admin/_header.html.erb +0 -0
@@ -71,6 +71,7 @@ module Decidim
|
|
71
71
|
|
72
72
|
private
|
73
73
|
|
74
|
+
# rubocop:disable Style/OpenStructUse
|
74
75
|
def menu_item
|
75
76
|
item = current_items.find { |i| md5(i.url) == params[:id] }
|
76
77
|
raise ActiveRecord::RecordNotFound unless item
|
@@ -84,6 +85,7 @@ module Decidim
|
|
84
85
|
native?: !item.respond_to?(:overrided?)
|
85
86
|
)
|
86
87
|
end
|
88
|
+
# rubocop:enable Style/OpenStructUse
|
87
89
|
|
88
90
|
def current_items
|
89
91
|
@current_items ||= current_menu.items(include_invisible: true)
|
@@ -32,8 +32,6 @@ module Decidim
|
|
32
32
|
# Rescue ajax calls and print the update.js view which prints the info on the message ajax form
|
33
33
|
# Only if the request is AJAX, otherwise behave as Decidim standards
|
34
34
|
def ajax_user_has_no_permission
|
35
|
-
return user_has_no_permission unless request.xhr?
|
36
|
-
|
37
35
|
render json: { message: I18n.t("actions.unauthorized", scope: "decidim.core") }, status: :unprocessable_entity
|
38
36
|
end
|
39
37
|
|
@@ -22,12 +22,26 @@ module Decidim
|
|
22
22
|
attribute :intergram_for_admins_settings, IntergramForm
|
23
23
|
attribute :intergram_for_public, Boolean
|
24
24
|
attribute :intergram_for_public_settings, IntergramForm
|
25
|
+
attribute :validate_title_min_length, Integer, default: 15
|
26
|
+
attribute :validate_title_max_caps_percent, Integer, default: 25
|
27
|
+
attribute :validate_title_max_marks_together, Integer, default: 1
|
28
|
+
attribute :validate_title_start_with_caps, Boolean, default: true
|
29
|
+
attribute :validate_body_min_length, Integer, default: 15
|
30
|
+
attribute :validate_body_max_caps_percent, Integer, default: 25
|
31
|
+
attribute :validate_body_max_marks_together, Integer, default: 1
|
32
|
+
attribute :validate_body_start_with_caps, Boolean, default: true
|
25
33
|
|
26
34
|
# collect all keys anything not specified in the params (UpdateConfig command ignores it)
|
27
35
|
attr_accessor :valid_keys
|
28
36
|
|
29
37
|
validate :css_syntax, if: ->(form) { form.scoped_styles.present? }
|
30
38
|
validate :json_syntax, if: ->(form) { form.proposal_custom_fields.present? }
|
39
|
+
validates :validate_title_min_length, presence: true, numericality: { greater_than_or_equal_to: 1, less_than_or_equal_to: 100 }
|
40
|
+
validates :validate_title_max_caps_percent, presence: true, numericality: { greater_than_or_equal_to: 0, less_than_or_equal_to: 100 }
|
41
|
+
validates :validate_title_max_marks_together, presence: true, numericality: { greater_than_or_equal_to: 1 }
|
42
|
+
validates :validate_body_min_length, presence: true, numericality: { greater_than_or_equal_to: 0 }
|
43
|
+
validates :validate_body_max_caps_percent, presence: true, numericality: { greater_than_or_equal_to: 0, less_than_or_equal_to: 100 }
|
44
|
+
validates :validate_body_max_marks_together, presence: true, numericality: { greater_than_or_equal_to: 1 }
|
31
45
|
|
32
46
|
# TODO: validate non general admins are here
|
33
47
|
|
@@ -5,7 +5,7 @@ module Decidim
|
|
5
5
|
module Admin
|
6
6
|
class MenuForm < Decidim::Form
|
7
7
|
include Decidim::TranslatableAttributes
|
8
|
-
VISIBILITY_STATES = %w(default hidden logged non_logged).freeze
|
8
|
+
VISIBILITY_STATES = %w(default hidden logged non_logged verified_user).freeze
|
9
9
|
|
10
10
|
translatable_attribute :raw_label, String
|
11
11
|
attribute :url, String
|
data/app/forms/decidim/decidim_awesome/proposals/proposal_wizard_create_step_form_override.rb
CHANGED
@@ -11,11 +11,15 @@ module Decidim
|
|
11
11
|
clear_validators!
|
12
12
|
|
13
13
|
validates :title, presence: true, etiquette: true
|
14
|
-
validates :title,
|
15
|
-
|
14
|
+
validates :title, proposal_length: {
|
15
|
+
minimum: ->(form) { form.minimum_title_length },
|
16
|
+
maximum: 150
|
17
|
+
}
|
18
|
+
validates :body, presence: true, unless: ->(form) { form.override_validations? || form.minimum_body_length.zero? }
|
19
|
+
validates :body, etiquette: true, unless: ->(form) { form.override_validations? }
|
16
20
|
validates :body, proposal_length: {
|
17
|
-
minimum:
|
18
|
-
maximum: ->(
|
21
|
+
minimum: ->(form) { form.minimum_body_length },
|
22
|
+
maximum: ->(form) { form.override_validations? ? 0 : form.component.settings.proposal_length }
|
19
23
|
}
|
20
24
|
|
21
25
|
validate :body_is_not_bare_template, unless: ->(form) { form.override_validations? }
|
@@ -23,13 +27,27 @@ module Decidim
|
|
23
27
|
def override_validations?
|
24
28
|
return false if context.current_component.settings.participatory_texts_enabled
|
25
29
|
|
26
|
-
custom_fields.present?
|
30
|
+
custom_fields.present? || awesome_config.enabled_for?(:use_markdown_editor)
|
31
|
+
end
|
32
|
+
|
33
|
+
def minimum_title_length
|
34
|
+
awesome_config.config[:validate_title_min_length].to_i
|
35
|
+
end
|
36
|
+
|
37
|
+
def minimum_body_length
|
38
|
+
awesome_config.config[:validate_body_min_length].to_i
|
27
39
|
end
|
28
40
|
|
29
41
|
def custom_fields
|
30
|
-
|
31
|
-
|
32
|
-
|
42
|
+
@custom_fields ||= awesome_config.collect_sub_configs_values("proposal_custom_field")
|
43
|
+
end
|
44
|
+
|
45
|
+
def awesome_config
|
46
|
+
@awesome_config ||= begin
|
47
|
+
conf = Decidim::DecidimAwesome::Config.new(context.current_organization)
|
48
|
+
conf.context_from_component(context.current_component)
|
49
|
+
conf
|
50
|
+
end
|
33
51
|
end
|
34
52
|
end
|
35
53
|
end
|
@@ -15,7 +15,11 @@ module Decidim
|
|
15
15
|
def menus
|
16
16
|
@menus ||= {
|
17
17
|
editors: config_enabled?([:allow_images_in_full_editor, :allow_images_in_small_editor, :use_markdown_editor, :allow_images_in_markdown_editor]),
|
18
|
-
proposals: config_enabled?(:allow_images_in_proposals
|
18
|
+
proposals: config_enabled?([:allow_images_in_proposals,
|
19
|
+
:validate_title_min_length, :validate_title_max_caps_percent,
|
20
|
+
:validate_title_max_marks_together, :validate_title_start_with_caps,
|
21
|
+
:validate_body_min_length, :validate_body_max_caps_percent,
|
22
|
+
:validate_body_max_marks_together, :validate_body_start_with_caps]),
|
19
23
|
surveys: config_enabled?(:auto_save_forms),
|
20
24
|
styles: config_enabled?(:scoped_styles),
|
21
25
|
proposal_custom_fields: config_enabled?(:proposal_custom_fields),
|
@@ -35,7 +39,7 @@ module Decidim
|
|
35
39
|
|
36
40
|
# ensure boolean value
|
37
41
|
def config_enabled?(var)
|
38
|
-
DecidimAwesome.enabled?(var)
|
42
|
+
DecidimAwesome.enabled?(var)
|
39
43
|
end
|
40
44
|
|
41
45
|
def participatory_space_manifests
|
@@ -49,18 +53,18 @@ module Decidim
|
|
49
53
|
def component_manifests(space = nil)
|
50
54
|
return {} if OTHER_MANIFESTS.include?(space)
|
51
55
|
|
52
|
-
Decidim.component_manifests.pluck(:name).
|
56
|
+
Decidim.component_manifests.pluck(:name).to_h do |name|
|
53
57
|
[name.to_sym, I18n.t("decidim.components.#{name}.name")]
|
54
|
-
end
|
58
|
+
end
|
55
59
|
end
|
56
60
|
|
57
61
|
def participatory_spaces_list(manifest)
|
58
62
|
space = model_for_manifest(manifest)
|
59
63
|
return {} if space.blank?
|
60
64
|
|
61
|
-
space.where(organization: current_organization).
|
65
|
+
space.where(organization: current_organization).to_h do |item|
|
62
66
|
[item.try(:slug) || item.id.to_s, translated_attribute(item.title)]
|
63
|
-
end
|
67
|
+
end
|
64
68
|
end
|
65
69
|
|
66
70
|
def components_list(manifest, slug)
|
@@ -68,9 +72,9 @@ module Decidim
|
|
68
72
|
return {} unless space&.column_names&.include? "slug"
|
69
73
|
|
70
74
|
components = Component.where(participatory_space: space.find_by(slug: slug))
|
71
|
-
components.
|
75
|
+
components.to_h do |item|
|
72
76
|
[item.id, "#{item.id}: #{translated_attribute(item.name)}"]
|
73
|
-
end
|
77
|
+
end
|
74
78
|
end
|
75
79
|
|
76
80
|
def translate_constraint_value(constraint, key)
|
@@ -98,16 +98,19 @@ module Decidim
|
|
98
98
|
builder = map_utility_dynamic.create_builder(self, options)
|
99
99
|
|
100
100
|
# We need awesome map listeners before initialize the official map
|
101
|
-
unless snippets.any?(:
|
102
|
-
snippets.add(:
|
103
|
-
snippets.add(:
|
104
|
-
snippets.add(:head, snippets.for(:
|
101
|
+
unless snippets.any?(:awesome_map_styles) || snippets.any?(:awesome_map_scripts)
|
102
|
+
snippets.add(:awesome_map_styles, stylesheet_pack_tag("decidim_decidim_awesome_map"))
|
103
|
+
snippets.add(:awesome_map_scripts, javascript_pack_tag("decidim_decidim_awesome_map", defer: false))
|
104
|
+
snippets.add(:head, snippets.for(:awesome_map_styles))
|
105
|
+
snippets.add(DecidimAwesome.legacy_version? ? :head : :foot, snippets.for(:awesome_map_scripts))
|
105
106
|
end
|
106
107
|
|
107
|
-
unless snippets.any?(:
|
108
|
-
snippets.add(:
|
109
|
-
snippets.add(:
|
110
|
-
|
108
|
+
unless snippets.any?(:map_styles) || snippets.any?(:map_scripts)
|
109
|
+
snippets.add(:map_styles, builder.stylesheet_snippets)
|
110
|
+
snippets.add(:map_scripts, builder.javascript_snippets)
|
111
|
+
|
112
|
+
snippets.add(:head, snippets.for(:map_styles))
|
113
|
+
snippets.add(DecidimAwesome.legacy_version? ? :head : :foot, snippets.for(:map_scripts))
|
111
114
|
end
|
112
115
|
|
113
116
|
builder
|
@@ -134,10 +137,10 @@ module Decidim
|
|
134
137
|
# rubocop:disable Naming/MethodParameterName
|
135
138
|
def hsv_to_rgb(h, s, v)
|
136
139
|
h_i = (h * 6).to_i
|
137
|
-
f = h * 6 - h_i
|
140
|
+
f = (h * 6) - h_i
|
138
141
|
p = v * (1 - s)
|
139
|
-
q = v * (1 - f * s)
|
140
|
-
t = v * (1 - (1 - f) * s)
|
142
|
+
q = v * (1 - (f * s))
|
143
|
+
t = v * (1 - ((1 - f) * s))
|
141
144
|
if h_i.zero?
|
142
145
|
r = v
|
143
146
|
g = t
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module DecidimAwesome
|
5
|
+
class ExportAdminActionsJob < ApplicationJob
|
6
|
+
queue_as :default
|
7
|
+
|
8
|
+
def perform(current_user, format, collection_ids)
|
9
|
+
collection = serialized_collection(collection_ids)
|
10
|
+
|
11
|
+
export_data = Exporters.find_exporter(format).new(collection).export
|
12
|
+
|
13
|
+
ExportMailer.export(current_user, "admin_actions", export_data).deliver_now
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def serialized_collection(collection_ids)
|
19
|
+
@serialized_collection ||= begin
|
20
|
+
collection = PaperTrailVersion.where(id: collection_ids)
|
21
|
+
collection.map do |item|
|
22
|
+
PaperTrailVersionSerializer.new(item).serialize
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# rubocop:disable Style/OpenStructUse
|
3
4
|
module Decidim
|
4
5
|
module DecidimAwesome
|
5
6
|
# A middleware that stores the current awesome context by parsing the request
|
@@ -85,6 +86,7 @@ module Decidim
|
|
85
86
|
end.flatten.uniq.map(&:to_i)
|
86
87
|
end
|
87
88
|
|
89
|
+
# rubocop:disable Lint/DuplicateBranch
|
88
90
|
# avoid unnecessary processing for non-user routes
|
89
91
|
def processable_path?
|
90
92
|
return true if safe_get_route?
|
@@ -121,6 +123,7 @@ module Decidim
|
|
121
123
|
true
|
122
124
|
end
|
123
125
|
end
|
126
|
+
# rubocop:enable Lint/DuplicateBranch
|
124
127
|
|
125
128
|
# to access certain deeper routes it requires first to click on a parent route, even without Post permissions in there
|
126
129
|
# this adds this additional routes to these cases
|
@@ -180,3 +183,4 @@ module Decidim
|
|
180
183
|
end
|
181
184
|
end
|
182
185
|
end
|
186
|
+
# rubocop:enable Style/OpenStructUse
|
@@ -10,9 +10,6 @@ module Decidim
|
|
10
10
|
belongs_to :author, foreign_key: :decidim_author_id, class_name: "Decidim::User"
|
11
11
|
belongs_to :organization, foreign_key: :decidim_organization_id, class_name: "Decidim::Organization"
|
12
12
|
|
13
|
-
validates :organization, presence: true
|
14
|
-
validates :author, presence: true
|
15
|
-
|
16
13
|
has_one_attached :file
|
17
14
|
validates_upload :file, uploader: Decidim::DecidimAwesome::ImageUploader
|
18
15
|
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module DecidimAwesome
|
5
|
+
class PaperTrailVersion < PaperTrail::Version
|
6
|
+
default_scope { order("created_at DESC") }
|
7
|
+
|
8
|
+
def self.safe_user_roles
|
9
|
+
DecidimAwesome.participatory_space_roles.filter(&:safe_constantize)
|
10
|
+
end
|
11
|
+
|
12
|
+
scope :space_role_actions, -> { where(item_type: PaperTrailVersion.safe_user_roles, event: "create") }
|
13
|
+
|
14
|
+
def self.admin_role_actions(filter = nil)
|
15
|
+
base = where(item_type: "Decidim::UserBaseEntity", event: %w(create update))
|
16
|
+
case filter
|
17
|
+
when nil
|
18
|
+
base.where("object_changes LIKE '%\nroles:\n- []\n- - %' OR object_changes LIKE '%\nadmin:\n- false\n- true%'")
|
19
|
+
when "admin"
|
20
|
+
base.where("object_changes LIKE '%\nadmin:\n- false\n- true%'")
|
21
|
+
else
|
22
|
+
base.where(Arel.sql("object_changes LIKE '%\nroles:\n- []\n- - #{filter}\n%'"))
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def present(html: true)
|
27
|
+
@present ||= if item_type == "Decidim::UserBaseEntity"
|
28
|
+
UserEntityPresenter.new(self, html: html)
|
29
|
+
elsif item_type.in?(PaperTrailVersion.safe_user_roles)
|
30
|
+
ParticipatorySpaceRolePresenter.new(self, html: html)
|
31
|
+
else
|
32
|
+
self
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
ransacker :role_type do
|
37
|
+
@role_type ||= begin
|
38
|
+
queries = PaperTrailVersion.safe_user_roles.map do |role_class|
|
39
|
+
table = role_class.safe_constantize.table_name
|
40
|
+
%{
|
41
|
+
SELECT ("#{table}"."role")::text FROM "#{table}"
|
42
|
+
WHERE "#{table}"."id" = "versions"."item_id"
|
43
|
+
AND item_type = '#{role_class}'
|
44
|
+
}
|
45
|
+
end
|
46
|
+
Arel.sql("(#{queries.join(" UNION ")})")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
ransacker :participatory_space_type do
|
51
|
+
Arel.sql(%{("item_type")::text})
|
52
|
+
end
|
53
|
+
|
54
|
+
ransacker :user_email do
|
55
|
+
@user_email ||= begin
|
56
|
+
queries = PaperTrailVersion.safe_user_roles.map do |role_class|
|
57
|
+
table = role_class.safe_constantize.table_name
|
58
|
+
%(
|
59
|
+
SELECT decidim_users.email FROM decidim_users
|
60
|
+
JOIN #{table} ON decidim_users.id = #{table}.decidim_user_id
|
61
|
+
WHERE #{table}.id = versions.item_id
|
62
|
+
AND item_type = '#{role_class}'
|
63
|
+
)
|
64
|
+
end
|
65
|
+
queries << %(
|
66
|
+
SELECT decidim_users.email FROM decidim_users
|
67
|
+
WHERE decidim_users.id = versions.item_id
|
68
|
+
AND item_type = 'Decidim::UserBaseEntity'
|
69
|
+
)
|
70
|
+
Arel.sql("(#{queries.join(" UNION ")})")
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
ransacker :user_name do
|
75
|
+
@user_name ||= begin
|
76
|
+
queries = PaperTrailVersion.safe_user_roles.map do |role_class|
|
77
|
+
table = role_class.safe_constantize.table_name
|
78
|
+
%(
|
79
|
+
SELECT decidim_users.name FROM decidim_users
|
80
|
+
JOIN #{table} ON decidim_users.id = #{table}.decidim_user_id
|
81
|
+
WHERE #{table}.id = versions.item_id
|
82
|
+
AND item_type = '#{role_class}'
|
83
|
+
)
|
84
|
+
end
|
85
|
+
queries << %(
|
86
|
+
SELECT decidim_users.name FROM decidim_users
|
87
|
+
WHERE decidim_users.id = versions.item_id
|
88
|
+
AND item_type = 'Decidim::UserBaseEntity'
|
89
|
+
)
|
90
|
+
Arel.sql("(#{queries.join(" UNION ")})")
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
ransacker :created_at, type: :date do
|
95
|
+
Arel.sql("date(created_at)")
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -1,5 +1,6 @@
|
|
1
|
-
import "src/decidim/decidim_awesome/awesome_admin"
|
2
|
-
|
1
|
+
import "src/decidim/decidim_awesome/awesome_admin";
|
2
|
+
// This is needed by custom fields builder but if loader there duplicates the jQuery inclusion
|
3
|
+
import "jquery-ui/ui/widgets/sortable";
|
3
4
|
|
4
5
|
// CSS
|
5
6
|
import "entrypoints/decidim_admin_decidim_awesome.scss";
|
Binary file
|
@@ -1,13 +1,13 @@
|
|
1
1
|
$(() => {
|
2
2
|
let CustomFieldsBuilders = window.CustomFieldsBuilders || [];
|
3
3
|
|
4
|
-
$("body").on("click", "a.awesome-auto-edit", (
|
5
|
-
|
6
|
-
const $link = $(
|
4
|
+
$("body").on("click", "a.awesome-auto-edit", (ev) => {
|
5
|
+
ev.preventDefault();
|
6
|
+
const $link = $(ev.currentTarget);
|
7
7
|
const scope = $link.data("scope");
|
8
8
|
const $target = $(`span.awesome-auto-edit[data-scope="${scope}"]`);
|
9
9
|
const $constraints = $(`.constraints-editor[data-key="${scope}"]`);
|
10
|
-
if ($target.length
|
10
|
+
if ($target.length === 0) {
|
11
11
|
return;
|
12
12
|
}
|
13
13
|
|
@@ -41,7 +41,7 @@ $(() => {
|
|
41
41
|
$container.attr("data-key", result.key);
|
42
42
|
$delete.attr("href", $delete.attr("href").replace(`key=${key}`, `key=${result.key}`))
|
43
43
|
CustomFieldsBuilders.forEach((builder) => {
|
44
|
-
if (builder.key
|
44
|
+
if (builder.key === key) {
|
45
45
|
builder.key = result.key;
|
46
46
|
}
|
47
47
|
});
|
@@ -52,12 +52,12 @@ $(() => {
|
|
52
52
|
$link.hide();
|
53
53
|
$input.select();
|
54
54
|
$input.on("keypress", (evt) => {
|
55
|
-
if (evt.code
|
55
|
+
if (evt.code === "Enter" || evt.code === "13" || evt.code === "10") {
|
56
56
|
evt.preventDefault();
|
57
57
|
$.ajax(
|
58
58
|
{
|
59
59
|
type: "POST",
|
60
|
-
url: DecidimAwesome.rename_scope_label_path,
|
60
|
+
url: window.DecidimAwesome.rename_scope_label_path,
|
61
61
|
dataType: "json",
|
62
62
|
headers: {
|
63
63
|
"X-CSRF-Token": $("meta[name=csrf-token]").attr("content")
|
@@ -14,13 +14,13 @@ $(() => {
|
|
14
14
|
|
15
15
|
let type = response.type;
|
16
16
|
let status = response.status;
|
17
|
-
if (response.type
|
17
|
+
if (response.type === "opaqueredirect") {
|
18
18
|
type = "redirect";
|
19
19
|
status = "302";
|
20
20
|
}
|
21
21
|
|
22
22
|
if (item.active) {
|
23
|
-
if (type
|
23
|
+
if (type === "redirect") {
|
24
24
|
$td.addClass("success");
|
25
25
|
} else {
|
26
26
|
$td.addClass("alert");
|
@@ -4,9 +4,9 @@ $(() => {
|
|
4
4
|
return;
|
5
5
|
}
|
6
6
|
|
7
|
-
$(".decidim_awesome-form").on("click", ".constraints-editor .add-condition,.constraints-editor .edit-condition", (
|
8
|
-
|
9
|
-
const $this = $(
|
7
|
+
$(".decidim_awesome-form").on("click", ".constraints-editor .add-condition,.constraints-editor .edit-condition", (evt) => {
|
8
|
+
evt.preventDefault();
|
9
|
+
const $this = $(evt.target)
|
10
10
|
const url = $this.attr("href");
|
11
11
|
const $callout = $this.closest(".constraints-editor").find(".callout");
|
12
12
|
$callout.hide();
|
@@ -21,8 +21,8 @@ $(() => {
|
|
21
21
|
});
|
22
22
|
|
23
23
|
// Custom event listener to reload the modal if needed
|
24
|
-
document.body.addEventListener("constraint:change", (
|
25
|
-
const vars =
|
24
|
+
document.body.addEventListener("constraint:change", (evt) => {
|
25
|
+
const vars = evt.detail.map((setting) => `${setting.key}=${setting.value}`);
|
26
26
|
const url = `${$modal.data("url")}&${vars.join("&")}`;
|
27
27
|
// console.log("constraint:change vars:", vars, "url:", url)
|
28
28
|
$modal.addClass("loading");
|
@@ -36,7 +36,8 @@ $(() => {
|
|
36
36
|
"paragraph"
|
37
37
|
],
|
38
38
|
disabledSubtypes: {
|
39
|
-
|
39
|
+
// default color as it generate hashtags in decidim (TODO: fix hashtag generator with this)
|
40
|
+
text: ["color"],
|
40
41
|
// disable default wysiwyg editors as they present problems
|
41
42
|
textarea: ["tinymce", "quill"]
|
42
43
|
}
|
@@ -45,21 +46,21 @@ $(() => {
|
|
45
46
|
});
|
46
47
|
});
|
47
48
|
|
48
|
-
$(document).on("formBuilder.create", (_event,
|
49
|
-
if (!list[
|
49
|
+
$(document).on("formBuilder.create", (_event, idx, list) => {
|
50
|
+
if (!list[idx]) {
|
50
51
|
return;
|
51
52
|
}
|
52
53
|
|
53
|
-
$(list[
|
54
|
-
list[
|
54
|
+
$(list[idx].el).formBuilder(list[idx].config).promise.then(function(res) {
|
55
|
+
list[idx].instance = res;
|
55
56
|
// Attach to DOM
|
56
|
-
list[
|
57
|
+
list[idx].el.FormBuilder = res;
|
57
58
|
// remove spinner
|
58
|
-
$(list[
|
59
|
+
$(list[idx].el).find(".loading-spinner").remove();
|
59
60
|
// for external use
|
60
|
-
$(document).trigger("formBuilder.created", [list[
|
61
|
-
if (
|
62
|
-
$(document).trigger("formBuilder.create", [
|
61
|
+
$(document).trigger("formBuilder.created", [list[idx]]);
|
62
|
+
if (idx < list.length) {
|
63
|
+
$(document).trigger("formBuilder.create", [idx + 1, list]);
|
63
64
|
}
|
64
65
|
});
|
65
66
|
});
|
@@ -67,13 +67,13 @@ export default class Fetcher {
|
|
67
67
|
}
|
68
68
|
|
69
69
|
findTranslation(translations) {
|
70
|
-
let
|
71
|
-
|
70
|
+
let lang = document.querySelector("html").getAttribute("lang"),
|
71
|
+
text = "";
|
72
72
|
|
73
|
-
translations.forEach((
|
74
|
-
if (
|
75
|
-
if (!text ||
|
76
|
-
text =
|
73
|
+
translations.forEach((txt) => {
|
74
|
+
if (txt.text) {
|
75
|
+
if (!text || txt.locale === lang) {
|
76
|
+
text = txt.text
|
77
77
|
}
|
78
78
|
}
|
79
79
|
});
|
@@ -85,12 +85,10 @@ export default class Fetcher {
|
|
85
85
|
if (text) {
|
86
86
|
const gids = text.match(/gid:\/\/[^\s<&]+/g)
|
87
87
|
if (gids) {
|
88
|
-
tags = gids.filter((gid) => gid.indexOf("/Decidim::Hashtag/")
|
88
|
+
tags = gids.filter((gid) => gid.indexOf("/Decidim::Hashtag/") !== -1).map((gid) => {
|
89
89
|
const parts = gid.split("/");
|
90
|
-
const fromSelector = parts[5].charAt(0)
|
91
|
-
const tag = fromSelector
|
92
|
-
? parts[5].substr(1)
|
93
|
-
: parts[5];
|
90
|
+
const fromSelector = parts[5].charAt(0) === "_";
|
91
|
+
const tag = fromSelector ? parts[5].substr(1) : parts[5]; // eslint-disable-line no-ternary, multiline-ternary
|
94
92
|
const name = `#${tag}`;
|
95
93
|
const html = `<a href="/search?term=${name}">${name}</a>`;
|
96
94
|
const hashtag = {
|
@@ -110,7 +108,8 @@ export default class Fetcher {
|
|
110
108
|
return tags;
|
111
109
|
}
|
112
110
|
|
113
|
-
replaceHashtags(
|
111
|
+
replaceHashtags(txt, hashtags) {
|
112
|
+
let text = txt;
|
114
113
|
hashtags.forEach((tag) => {
|
115
114
|
text = text.replace(tag.gid, tag.name)
|
116
115
|
});
|
@@ -121,7 +120,8 @@ export default class Fetcher {
|
|
121
120
|
return text.replace(/gid:\/\/[^\s<&]+/g, "");
|
122
121
|
}
|
123
122
|
|
124
|
-
appendHtmlHashtags(
|
123
|
+
appendHtmlHashtags(txt, tags) {
|
124
|
+
let text = txt;
|
125
125
|
tags.forEach((tag) => {
|
126
126
|
text += ` ${tag.html}`;
|
127
127
|
});
|