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.
Files changed (137) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +32 -9
  3. data/app/assets/config/decidim_admin_decidim_awesome_manifest.css +2 -2
  4. data/app/assets/config/decidim_admin_decidim_awesome_manifest.js +1 -2
  5. data/app/assets/config/decidim_decidim_awesome_manifest.css +2 -2
  6. data/app/assets/config/decidim_decidim_awesome_manifest.js +3 -2
  7. data/app/assets/config/legacy_decidim_admin_decidim_awesome_manifest.js +2 -0
  8. data/app/assets/config/legacy_decidim_decidim_awesome_manifest.js +4 -0
  9. data/app/assets/javascripts/decidim/decidim_awesome/admin/auto_edit.js.es6 +77 -0
  10. data/app/assets/javascripts/decidim/decidim_awesome/admin/codemirror.js.es6 +2 -3
  11. data/app/assets/javascripts/decidim/decidim_awesome/admin/form_builder.js.es6 +80 -0
  12. data/app/assets/javascripts/decidim/decidim_awesome/admin/legacy_form_builder.js.es6 +80 -0
  13. data/app/assets/javascripts/decidim/decidim_awesome/admin/user_picker.js.es6 +24 -0
  14. data/app/assets/javascripts/decidim/decidim_awesome/awesome_admin.js +7 -0
  15. data/app/assets/javascripts/decidim/decidim_awesome/{application.js → awesome_application.js} +1 -2
  16. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/layers.js.es6 +3 -2
  17. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/load_map.js.es6 +15 -0
  18. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/map.js.es6 +52 -56
  19. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/meetings.js.es6 +2 -2
  20. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/proposals.js.es6 +1 -1
  21. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/utilities.js.es6 +33 -24
  22. data/app/assets/javascripts/decidim/decidim_awesome/editors/legacy_quill_editor.js.es6 +14 -2
  23. data/app/assets/javascripts/decidim/decidim_awesome/editors/quill_editor.js.es6 +18 -4
  24. data/app/assets/javascripts/decidim/decidim_awesome/editors/tabs_focus.js.es6 +24 -0
  25. data/app/assets/javascripts/decidim/decidim_awesome/forms/custom_fields_builder.js.es6 +211 -0
  26. data/app/assets/javascripts/decidim/decidim_awesome/forms/rich_text_plugin.js.es6 +106 -0
  27. data/app/assets/javascripts/decidim/decidim_awesome/legacy_admin.js +5 -1
  28. data/app/assets/javascripts/decidim/decidim_awesome/legacy_application.js +0 -1
  29. data/app/assets/javascripts/decidim/decidim_awesome/proposals/custom_fields.js.es6 +21 -0
  30. data/app/assets/stylesheets/decidim/decidim_awesome/admin/auto_edits.scss +15 -0
  31. data/app/assets/stylesheets/decidim/decidim_awesome/admin/codemirror.scss +15 -4
  32. data/app/assets/stylesheets/decidim/decidim_awesome/admin/constraints.scss +12 -0
  33. data/app/assets/stylesheets/decidim/decidim_awesome/admin/custom_fields.scss +66 -0
  34. data/app/assets/stylesheets/decidim/decidim_awesome/admin/user_picker.scss +35 -0
  35. data/app/assets/stylesheets/decidim/decidim_awesome/{admin.scss → awesome_admin.scss} +12 -0
  36. data/app/assets/stylesheets/decidim/decidim_awesome/awesome_application.scss +22 -0
  37. data/app/assets/stylesheets/decidim/decidim_awesome/awesome_map/map.scss +0 -1
  38. data/app/assets/stylesheets/decidim/decidim_awesome/editors/quill_editor.scss +16 -1
  39. data/app/awesome_overrides/forms/decidim/proposals/proposal_wizard_create_step_form_override.rb +28 -0
  40. data/app/cells/decidim/decidim_awesome/content_blocks/map/show.erb +74 -0
  41. data/app/cells/decidim/decidim_awesome/content_blocks/map_cell.rb +54 -0
  42. data/app/cells/decidim/decidim_awesome/content_blocks/map_form/show.erb +61 -0
  43. data/app/cells/decidim/decidim_awesome/content_blocks/map_form_cell.rb +19 -0
  44. data/app/commands/concerns/decidim/decidim_awesome/admin/needs_constraint_helpers.rb +32 -0
  45. data/app/commands/decidim/decidim_awesome/admin/create_proposal_custom_field.rb +45 -0
  46. data/app/commands/decidim/decidim_awesome/admin/create_scoped_admin.rb +38 -0
  47. data/app/commands/decidim/decidim_awesome/admin/destroy_constraint.rb +4 -0
  48. data/app/commands/decidim/decidim_awesome/admin/destroy_proposal_custom_field.rb +40 -0
  49. data/app/commands/decidim/decidim_awesome/admin/destroy_scoped_admin.rb +40 -0
  50. data/app/commands/decidim/decidim_awesome/admin/destroy_scoped_style.rb +1 -1
  51. data/app/commands/decidim/decidim_awesome/admin/rename_scope_label.rb +58 -0
  52. data/app/commands/decidim/decidim_awesome/admin/update_config.rb +1 -0
  53. data/app/controllers/concerns/decidim/decidim_awesome/admin_not_found_redirect.rb +39 -0
  54. data/app/controllers/decidim/decidim_awesome/admin/config_controller.rb +31 -18
  55. data/app/controllers/decidim/decidim_awesome/admin/constraints_controller.rb +4 -0
  56. data/app/controllers/decidim/decidim_awesome/admin/proposal_custom_fields_controller.rb +38 -0
  57. data/app/controllers/decidim/decidim_awesome/admin/scoped_admins_controller.rb +38 -0
  58. data/app/controllers/decidim/decidim_awesome/admin/scoped_styles_controller.rb +38 -0
  59. data/app/forms/decidim/decidim_awesome/admin/config_form.rb +39 -0
  60. data/app/forms/decidim/decidim_awesome/admin/constraint_form.rb +3 -1
  61. data/app/helpers/decidim/decidim_awesome/admin/config_constraints_helpers.rb +11 -7
  62. data/app/helpers/decidim/decidim_awesome/amendments_helper_override.rb +48 -0
  63. data/app/helpers/decidim/decidim_awesome/map_helper.rb +67 -16
  64. data/app/helpers/decidim/decidim_awesome/proposals/application_helper_override.rb +78 -0
  65. data/app/middleware/decidim/decidim_awesome/current_config.rb +182 -0
  66. data/app/models/decidim/decidim_awesome/awesome_config.rb +15 -0
  67. data/app/models/decidim/decidim_awesome/user_override.rb +25 -0
  68. data/app/permissions/decidim/decidim_awesome/admin/permissions.rb +2 -0
  69. data/app/views/decidim/decidim_awesome/admin/checks/index.html.erb +1 -1
  70. data/app/views/decidim/decidim_awesome/admin/config/_autoedit_box_label.html.erb +7 -0
  71. data/app/views/decidim/decidim_awesome/admin/config/_constraints.html.erb +2 -2
  72. data/app/views/decidim/decidim_awesome/admin/config/_form_admins.html.erb +21 -0
  73. data/app/views/decidim/decidim_awesome/admin/config/_form_editors.html.erb +0 -3
  74. data/app/views/decidim/decidim_awesome/admin/config/_form_proposal_custom_fields.html.erb +25 -0
  75. data/app/views/decidim/decidim_awesome/admin/config/_form_proposals.html.erb +0 -2
  76. data/app/views/decidim/decidim_awesome/admin/config/_form_styles.html.erb +4 -7
  77. data/app/views/decidim/decidim_awesome/admin/proposals/_editor.html.erb +4 -0
  78. data/app/views/decidim/decidim_awesome/custom_fields/_form_render.html.erb +6 -0
  79. data/app/views/decidim/decidim_awesome/map_component/map/show.html.erb +0 -2
  80. data/app/views/decidim/proposals/admin/proposals/_form.html.erb +101 -0
  81. data/app/views/decidim/proposals/collaborative_drafts/_edit_form_fields.html.erb +83 -0
  82. data/app/views/decidim/proposals/collaborative_drafts/show.html.erb +1 -0
  83. data/app/views/layouts/decidim/admin/decidim_awesome.html.erb +25 -11
  84. data/app/views/layouts/decidim/decidim_awesome/_awesome_config.html.erb +4 -0
  85. data/app/views/layouts/decidim/decidim_awesome/_custom_styles.html.erb +1 -1
  86. data/app/views/v0.23/decidim/proposals/collaborative_drafts/_show.html.erb +134 -0
  87. data/app/views/v0.23/layouts/decidim/_head.html.erb +1 -1
  88. data/app/views/v0.23/layouts/decidim/admin/_header.html.erb +1 -1
  89. data/app/views/v0.24/decidim/proposals/collaborative_drafts/_show.html.erb +128 -0
  90. data/app/views/v0.24/layouts/decidim/_head.html.erb +2 -2
  91. data/app/views/v0.24/layouts/decidim/admin/_header.html.erb +2 -2
  92. data/config/locales/ca.yml +62 -3
  93. data/config/locales/cs.yml +62 -3
  94. data/config/locales/en.yml +90 -11
  95. data/config/locales/es.yml +61 -2
  96. data/config/locales/eu.yml +63 -4
  97. data/config/locales/fr.yml +62 -3
  98. data/config/locales/it.yml +284 -0
  99. data/config/locales/ja.yml +284 -0
  100. data/config/locales/nl.yml +62 -3
  101. data/config/locales/sv.yml +62 -3
  102. data/db/migrate/20210628150825_change_awesome_config_var_type.rb +12 -0
  103. data/lib/decidim/decidim_awesome/admin_engine.rb +16 -4
  104. data/lib/decidim/decidim_awesome/awesome_helpers.rb +17 -10
  105. data/lib/decidim/decidim_awesome/checksums.yml +17 -4
  106. data/lib/decidim/decidim_awesome/config.rb +53 -6
  107. data/lib/decidim/decidim_awesome/context_analyzers/request_analyzer.rb +27 -21
  108. data/lib/decidim/decidim_awesome/custom_fields.rb +94 -0
  109. data/lib/decidim/decidim_awesome/engine.rb +62 -6
  110. data/lib/decidim/decidim_awesome/test/shared_examples/box_label_editor.rb +116 -0
  111. data/lib/decidim/decidim_awesome/test/shared_examples/current_config_examples.rb +143 -0
  112. data/lib/decidim/decidim_awesome/test/shared_examples/editor_examples.rb +4 -0
  113. data/lib/decidim/decidim_awesome/test/shared_examples/scoped_admins_examples.rb +428 -0
  114. data/lib/decidim/decidim_awesome/version.rb +1 -1
  115. data/lib/decidim/decidim_awesome.rb +41 -8
  116. data/vendor/assets/javascripts/delta.min.js +405 -0
  117. data/vendor/assets/javascripts/delta.min.js.map +1 -0
  118. data/vendor/assets/javascripts/europa.min.js +4 -0
  119. data/vendor/assets/javascripts/form-builder.min.js +19 -0
  120. data/vendor/assets/javascripts/form-render.min.js +19 -0
  121. data/vendor/assets/javascripts/inscrybmde.min.js +1 -1
  122. data/vendor/assets/javascripts/jquery-ui.min.js +13 -0
  123. data/vendor/assets/javascripts/select2.js +6147 -0
  124. data/vendor/assets/langs/en-US.lang +110 -0
  125. data/vendor/assets/stylesheets/inscrybmde.min.scss +14 -0
  126. data/vendor/assets/stylesheets/jquery-ui.min.css +7 -0
  127. data/vendor/assets/stylesheets/select2-foundation-theme.css +249 -0
  128. data/vendor/assets/stylesheets/select2.css +515 -0
  129. metadata +68 -27
  130. data/app/assets/images/decidim/decidim_awesome/loading.gif +0 -0
  131. data/app/assets/javascripts/decidim/decidim_awesome/admin.js +0 -3
  132. data/app/assets/javascripts/decidim/decidim_awesome/editors/markdown_view.js.es6 +0 -12
  133. data/app/assets/stylesheets/decidim/decidim_awesome/application.scss +0 -8
  134. data/app/assets/stylesheets/decidim/decidim_awesome/editors/markdown_view.scss +0 -27
  135. data/app/awesome_overrides/presenters/decidim/proposals/proposal_presenter_override.rb +0 -58
  136. data/lib/decidim/decidim_awesome/content_renderers/markdown_renderer.rb +0 -18
  137. data/lib/decidim/decidim_awesome/content_renderers.rb +0 -9
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module DecidimAwesome
5
+ module Proposals
6
+ module ApplicationHelperOverride
7
+ extend ActiveSupport::Concern
8
+
9
+ included do
10
+ alias_method :decidim_text_editor_for_proposal_body, :text_editor_for_proposal_body
11
+ alias_method :decidim_safe_content?, :safe_content?
12
+
13
+ # replace safe content to consider all custom fields save (then embeded html will be rendered)
14
+ def safe_content?
15
+ awesome_proposal_custom_fields.present? || decidim_safe_content?
16
+ end
17
+
18
+ # replace normal method to draw the editor
19
+ def text_editor_for_proposal_body(form)
20
+ custom_fields = awesome_proposal_custom_fields
21
+
22
+ return decidim_text_editor_for_proposal_body(form) if custom_fields.blank?
23
+
24
+ render_proposal_custom_fields_override(custom_fields, form, :body)
25
+ end
26
+
27
+ # replace admin method to draw the editor (multi lang)
28
+ def admin_editor_for_proposal_body(form)
29
+ custom_fields = awesome_proposal_custom_fields
30
+
31
+ return form.translated(:editor, :body, hashtaggable: true) if custom_fields.blank?
32
+
33
+ locales = form.send(:locales)
34
+
35
+ return render_proposal_custom_fields_override(custom_fields, form, "body_#{locales.first}", locales.first) if locales.length == 1
36
+
37
+ tabs_id = form.send(:sanitize_tabs_selector, form.options[:tabs_id] || "#{form.object_name}-body-tabs")
38
+
39
+ label_tabs = form.content_tag(:div, class: "label--tabs") do
40
+ field_label = form.send(:label_i18n, "body", form.label_for("proposal_custom_fields"))
41
+
42
+ language_selector = "".html_safe
43
+ language_selector = form.create_language_selector(locales, tabs_id, "body") if form.options[:label] != false
44
+
45
+ safe_join [field_label, language_selector]
46
+ end
47
+
48
+ tabs_content = form.content_tag(:div, class: "tabs-content", data: { tabs_content: tabs_id }) do
49
+ locales.each_with_index.inject("".html_safe) do |string, (locale, index)|
50
+ tab_content_id = "#{tabs_id}-body-panel-#{index}"
51
+ string + content_tag(:div, class: form.send(:tab_element_class_for, "panel", index), id: tab_content_id) do
52
+ render_proposal_custom_fields_override(custom_fields, form, "body_#{locale}", locale)
53
+ end
54
+ end
55
+ end
56
+
57
+ safe_join [label_tabs, tabs_content]
58
+ end
59
+
60
+ def render_proposal_custom_fields_override(fields, form, name, locale = nil)
61
+ custom_fields = Decidim::DecidimAwesome::CustomFields.new(fields)
62
+ custom_fields.translate!
63
+
64
+ body = if form_presenter.proposal.body.is_a?(Hash) && locale
65
+ form_presenter.body(extras: false, all_locales: true)[locale]
66
+ else
67
+ form_presenter.body(extras: false)
68
+ end
69
+
70
+ custom_fields.apply_xml(body) if body.present?
71
+ form.object.errors.add(name, custom_fields.errors) if custom_fields.errors
72
+ render partial: "decidim/decidim_awesome/custom_fields/form_render", locals: { spec: custom_fields.to_json, form: form, name: name }
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,182 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module DecidimAwesome
5
+ # A middleware that stores the current awesome context by parsing the request
6
+ class CurrentConfig
7
+ # Initializes the Rack Middleware.
8
+ #
9
+ # app - The Rack application
10
+ def initialize(app)
11
+ @app = app
12
+ end
13
+
14
+ # Main entry point for a Rack Middleware.
15
+ #
16
+ # env - A Hash.
17
+ def call(env)
18
+ @request = Rack::Request.new(env)
19
+ if @request.env["decidim.current_organization"] && processable_path?
20
+ @config = awesome_config_instance
21
+ env["decidim_awesome.current_config"] = @config
22
+ tamper_user_model
23
+ add_flash_message_from_request(env)
24
+
25
+ # puts "requested path: #{env["PATH_INFO"]}"
26
+ # puts "current_organization: #{@request.env["decidim.current_organization"]&.id}"
27
+ # puts "potential_admins: #{Decidim::User.awesome_potential_admins}"
28
+ # puts "scoped admins: #{Decidim::User.awesome_admins_for_current_scope}"
29
+ else
30
+ reset_user_model
31
+ end
32
+
33
+ @app.call(env)
34
+ end
35
+
36
+ private
37
+
38
+ # a workaround to set a flash message if comming from the error controller (route not found)
39
+ def add_flash_message_from_request(env)
40
+ return unless scoped_admins_active?
41
+ return unless @request.params.has_key? "unauthorized"
42
+
43
+ env["rack.session"]["flash"] = ActionDispatch::Flash::FlashHash.new(alert: I18n.t("decidim.core.actions.unauthorized")).to_session_value
44
+ end
45
+
46
+ def awesome_config_instance
47
+ @awesome_config_instance = Config.new @request.env["decidim.current_organization"]
48
+ @awesome_config_instance.context_from_request @request
49
+ @awesome_config_instance
50
+ end
51
+
52
+ def reset_user_model
53
+ return unless scoped_admins_active?
54
+
55
+ Decidim::User.awesome_potential_admins = []
56
+ Decidim::User.awesome_admins_for_current_scope = []
57
+ end
58
+
59
+ def tamper_user_model
60
+ return unless scoped_admins_active?
61
+
62
+ Decidim::User.awesome_potential_admins = potential_admins
63
+
64
+ Decidim::User.awesome_admins_for_current_scope = if safe_get_route? || safe_post_route?
65
+ Decidim::User.awesome_potential_admins
66
+ else
67
+ valid_admins
68
+ end
69
+ end
70
+
71
+ def potential_admins
72
+ @config.collect_sub_configs_values("scoped_admin") do |subconfig|
73
+ subconfig&.constraints&.detect { |c| c.settings["participatory_space_manifest"] == "none" } ? false : true
74
+ end.flatten.uniq.map(&:to_i)
75
+ end
76
+
77
+ def valid_admins
78
+ @config.collect_sub_configs_values("scoped_admin") do |subconfig|
79
+ # allow index controllers if scoped to a subspace/component
80
+ constraints = subconfig&.constraints || []
81
+ additional_constraints = additional_get_constraints(constraints) + additional_post_constraints(constraints)
82
+ # inject additional constraints here for further use
83
+ @config.inject_sub_config_constraints("scoped_admin", subconfig.var[13..], additional_constraints) if subconfig
84
+ @config.valid_in_context?(constraints + additional_constraints)
85
+ end.flatten.uniq.map(&:to_i)
86
+ end
87
+
88
+ # avoid unnecessary processing for non-user routes
89
+ def processable_path?
90
+ return true if safe_get_route?
91
+
92
+ spaces = ContextAnalyzers::RequestAnalyzer.participatory_spaces_routes.keys.join("|^(/admin){0,1}/")
93
+ case @request.path
94
+ when %r{"|^(/admin){0,1}/#{spaces}}
95
+ true
96
+ when %r{^/admin/}
97
+ true
98
+ end
99
+ end
100
+
101
+ def safe_get_route?
102
+ return unless @request.get?
103
+
104
+ case @request.path
105
+ when "/"
106
+ true
107
+ when "/admin/"
108
+ true
109
+ when %r{^/admin/admin_terms}
110
+ true
111
+ when %r{^/profiles/|^/notifications/|^/conversations/|^/pages/}
112
+ true
113
+ end
114
+ end
115
+
116
+ def safe_post_route?
117
+ return unless @request.post? || @request.put? || @request.patch?
118
+
119
+ case @request.path
120
+ when %r{^/admin/admin_terms}
121
+ true
122
+ end
123
+ end
124
+
125
+ # to access certain deeper routes it requires first to click on a parent route, even without Post permissions in there
126
+ # this adds this additional routes to these cases
127
+ # For instance:
128
+ # accessing /admin/participatory_processes/som-procress requires access first to /admin/participatory_processes
129
+ def additional_get_constraints(constraints)
130
+ return [] unless @request.get?
131
+
132
+ additions = []
133
+ constraints.each do |constraint|
134
+ next if constraint.settings["participatory_space_manifest"].blank?
135
+
136
+ # processes groups must give access to processes generic url
137
+ if constraint.settings["participatory_space_manifest"] == "process_groups"
138
+ additions << OpenStruct.new(settings: { "participatory_space_manifest" => "participatory_processes", "match" => "exclusive" })
139
+ end
140
+
141
+ # adds a exclusive constraint to the parent participatory space (so index page can be accessed)
142
+ next unless constraint.settings.size > 1
143
+
144
+ additions << OpenStruct.new(settings: {
145
+ "participatory_space_manifest" => constraint.settings["participatory_space_manifest"],
146
+ "match" => "exclusive"
147
+ })
148
+ end
149
+
150
+ additions
151
+ end
152
+
153
+ # adds access to REST routes with id instead of the slug ot allow editing
154
+ # rubocop:disable Metrics/CyclomaticComplexity
155
+ # rubocop:disable Metrics/PerceivedComplexity
156
+ def additional_post_constraints(constraints)
157
+ return [] unless @request.post? || @request.patch?
158
+
159
+ constraints.filter_map do |constraint|
160
+ settings = constraint.settings.dup
161
+ next unless settings["participatory_space_manifest"].present? && settings["participatory_space_slug"].present?
162
+
163
+ # replicate the constraint with the id of the participatory space
164
+ manifest = Decidim.participatory_space_manifests.find { |s| s.name.to_s == settings["participatory_space_manifest"] }
165
+ next unless manifest
166
+
167
+ model = manifest.model_class_name.try(:constantize)
168
+ next unless model
169
+
170
+ settings["participatory_space_slug"] = model.find_by(slug: settings["participatory_space_slug"])&.id
171
+ OpenStruct.new(settings: settings) if settings["participatory_space_slug"]
172
+ end
173
+ end
174
+ # rubocop:enable Metrics/CyclomaticComplexity
175
+ # rubocop:enable Metrics/PerceivedComplexity
176
+
177
+ def scoped_admins_active?
178
+ Decidim::User.respond_to?(:awesome_admins_for_current_scope) && Decidim::User.respond_to?(:awesome_potential_admins)
179
+ end
180
+ end
181
+ end
182
+ end
@@ -15,9 +15,24 @@ module Decidim
15
15
  validates :organization, presence: true
16
16
  validates :var, uniqueness: { scope: :decidim_organization_id }
17
17
 
18
+ def additional_constraints
19
+ @additional_constraints ||= []
20
+ end
21
+
22
+ def add_constraints(constraints)
23
+ return if constraints.blank?
24
+
25
+ additional_constraints.concat(constraints.respond_to?(:each) ? constraints : [constraints])
26
+ end
27
+
18
28
  def self.for_organization(organization)
19
29
  where(organization: organization)
20
30
  end
31
+
32
+ # use this instead of "constraints" to evaluate dynamically added constants
33
+ def all_constraints
34
+ constraints + additional_constraints
35
+ end
21
36
  end
22
37
  end
23
38
  end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module DecidimAwesome
5
+ module UserOverride
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ class << self
10
+ attr_accessor :awesome_admins_for_current_scope, :awesome_potential_admins
11
+ end
12
+
13
+ def admin
14
+ return self["admin"] if self["admin"]
15
+
16
+ Decidim::User.awesome_admins_for_current_scope&.include?(id)
17
+ end
18
+
19
+ def admin?
20
+ admin.present?
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -8,6 +8,8 @@ module Decidim
8
8
 
9
9
  def permissions
10
10
  return permission_action if permission_action.scope != :admin
11
+ return permission_action unless user
12
+ return permission_action if user.read_attribute("admin").blank?
11
13
 
12
14
  toggle_allow(config_enabled?(permission_action.subject)) if permission_action.action == :edit_config
13
15
 
@@ -56,7 +56,7 @@
56
56
  <strong><%= t ".admin_head_tags" %></strong>
57
57
  <ul class="vertical menu">
58
58
  <% {
59
- CSS: "//link[@rel='stylesheet'][contains(@href,'decidim_awesome/admin')]",
59
+ CSS: "//link[@rel='stylesheet'][contains(@href,'decidim_awesome/awesome_admin')]",
60
60
  JavaScript: "//script[contains(@src,'decidim_awesome')]"
61
61
  }.each do |part, xpath| %>
62
62
  <li>
@@ -0,0 +1,7 @@
1
+ <%= label_tag var do %>
2
+ <%= t("config.#{var}",
3
+ scope: "activemodel.attributes",
4
+ id: "<span class='awesome-auto-edit' data-var='#{var}' data-scope='#{scope}' data-key='#{key}'>#{key}</span>").html_safe %>
5
+ <%= icon_link_to "pencil", "#", t("edit_label", scope: "decidim.decidim_awesome.admin.config.form"), class: "action-icon--edit awesome-auto-edit", data: { "scope" => "#{scope}" } %>
6
+ <%= link_to t("remove", scope: "decidim.decidim_awesome.admin.config.form_#{var}"), delete_path, method: :delete, class: "float-right delete-box", data: { confirm: t("sure_to_remove", scope: "decidim.decidim_awesome.admin.config.form_#{var}") } %>
7
+ <% end %>
@@ -11,11 +11,11 @@
11
11
  <span class="label warning"><%= t ".always" %></span>
12
12
  <% end %>
13
13
 
14
- <ul class="constraints-list">
14
+ <ul class="constraints-list<%= " inactive" if constraints&.detect{|c| c.settings["participatory_space_manifest"]=="none" } %>">
15
15
  <% constraints&.each do |constraint| %>
16
16
  <li>
17
17
  <% constraint.settings.reverse_each do |k, val| %>
18
- <span class="label <%= k %>"><%= translate_constraint_value constraint, k %></span>
18
+ <span class="label <%= k %> constraint-<%= val %>"><%= translate_constraint_value constraint, k %></span>
19
19
  <% end %>
20
20
  <a href="<%= constraint_path(id: constraint.id, key: key) %>" class="edit-condition"><%= t ".edit" %></a>
21
21
  <%= link_to t(".delete"), constraint_path(id: constraint.id), remote: true, method: :delete %>
@@ -0,0 +1,21 @@
1
+ <div class="row column decidim_awesome-form">
2
+ <% if config_enabled? :scoped_admins %>
3
+ <p class="help-text"><%= t("help.scoped_admins", scope: "decidim.decidim_awesome.admin.config.form") %></p>
4
+
5
+ <% form.object.scoped_admins&.each do |key, value| %>
6
+ <div class="scoped_admins_container" data-key="<%= key %>">
7
+ <%= render(partial: "decidim/decidim_awesome/admin/config/autoedit_box_label", locals: { var: "scoped_admins", key: key, scope: "scoped_admin_#{key}", delete_path: decidim_admin_decidim_awesome.scoped_admin_path(key: key) }) %>
8
+ <p class="form-error is-visible" id="scoped-admin-error-<%= $key %>"><%= errors[key.to_sym].join("<br>") if errors %></p>
9
+
10
+ <%= select_tag "config[scoped_admins][#{key}]", options_from_collection_for_select(users_for(value), :id, :text, proc { true }), { include_blank: false , class: "multiusers-select", multiple: true, data: { url: decidim_admin_decidim_awesome.users_path } } %>
11
+
12
+ <%= render(partial: "decidim/decidim_awesome/admin/config/constraints", locals: { key: "scoped_admin_#{key}", constraints: constraints_for("scoped_admin_#{key}") }) %>
13
+ </div>
14
+ <% end %>
15
+
16
+ <%= link_to t("new", scope: "decidim.decidim_awesome.admin.config.form_scoped_admins"), decidim_admin_decidim_awesome.scoped_admins_path, method: :post %>
17
+
18
+ <% end %>
19
+ </div>
20
+
21
+ <%= javascript_include_tag "decidim/decidim_awesome/admin/form_exit_warn" %>
@@ -8,13 +8,10 @@
8
8
  <%= render(partial: "decidim/decidim_awesome/admin/config/constraints", locals: { key: key, constraints: constraints_for(key) }) %>
9
9
  <% end %>
10
10
 
11
- <h2 class="card-title"><%= t("experimental", scope: "decidim.decidim_awesome.admin.config") %></h2>
12
-
13
11
  <% enabled_configs([:use_markdown_editor, :allow_images_in_markdown_editor]).each do |key| %>
14
12
  <%= form.check_box key %>
15
13
  <p class="help-text"><%= t("help.#{key}", scope: "decidim.decidim_awesome.admin.config.form") %></p>
16
14
 
17
15
  <%= render(partial: "decidim/decidim_awesome/admin/config/constraints", locals: { key: key, constraints: constraints_for(key) }) %>
18
16
  <% end %>
19
-
20
17
  </div>
@@ -0,0 +1,25 @@
1
+ <div class="callout warning"><%= t("caution", scope: "decidim.decidim_awesome.admin.config") %></div>
2
+ <div class="row column decidim_awesome-form">
3
+ <% if config_enabled? :proposal_custom_fields %>
4
+ <p class="help-text"><%= t("help.proposal_custom_fields", scope: "decidim.decidim_awesome.admin.config.form") %></p>
5
+ <p class="help-text"><%= t("help.proposal_custom_fields_example", scope: "decidim.decidim_awesome.admin.config.form") %></p>
6
+ <p class="help-text"><%= t("help.proposal_custom_fields_translations", scope: "decidim.decidim_awesome.admin.config.form") %></p>
7
+
8
+ <% form.object.proposal_custom_fields&.each do |key, value| %>
9
+ <div class="proposal_custom_fields_container" data-key="<%= key %>">
10
+ <%= render(partial: "decidim/decidim_awesome/admin/config/autoedit_box_label", locals: { var: "proposal_custom_fields", key: key, scope: "proposal_custom_field_#{key}", delete_path: decidim_admin_decidim_awesome.proposal_custom_field_path(key: key) }) %>
11
+ <p class="form-error is-visible"><%= errors[key.to_sym].join("<br>") if errors %></p>
12
+ <%= hidden_field_tag key, value, name: "config[proposal_custom_fields][#{key}]" %>
13
+ <div class="proposal_custom_fields_editor">
14
+ <div class="loading-spinner"></div>
15
+ </div>
16
+ <%= render(partial: "decidim/decidim_awesome/admin/config/constraints", locals: { key: "proposal_custom_field_#{key}", constraints: constraints_for("proposal_custom_field_#{key}") }) %>
17
+ </div>
18
+ <% end %>
19
+
20
+ <%= link_to t(".new"), decidim_admin_decidim_awesome.proposal_custom_fields_path, method: :post %>
21
+
22
+ <% end %>
23
+ </div>
24
+
25
+ <%= javascript_include_tag "decidim/decidim_awesome/admin/form_exit_warn" %>
@@ -1,6 +1,4 @@
1
1
  <div class="row column decidim_awesome-form">
2
- <h2 class="card-title"><%= t("experimental", scope: "decidim.decidim_awesome.admin.config") %></h2>
3
-
4
2
  <% if config_enabled? :allow_images_in_proposals %>
5
3
  <p class="text-info"><%= t("rich_text_editor_in_public_views", scope: "decidim.decidim_awesome.admin.config") if current_organization.rich_text_editor_in_public_views %></p>
6
4
 
@@ -9,18 +9,15 @@
9
9
  </p>
10
10
 
11
11
  <% form.object.scoped_styles&.each do |key, value| %>
12
- <div class="scoped-style" data-key="<%= key %>">
13
- <%= label_tag :scoped_styles do %>
14
- <%= t("config.scoped_styles", scope: "activemodel.attributes", id: key) %>
15
- <%= link_to t(".remove"), decidim_admin_decidim_awesome.destroy_scoped_style_path(key: key), method: :post, class: "float-right", data: { confirm: t(".sure_to_remove") } %>
16
- <% end %>
17
- <p class="form-error is-visible" id="custom-style-error-<%= $key %>"><%= errors[key.to_sym].join("<br>") if errors %></p>
12
+ <div class="scoped_styles_container" data-key="<%= key %>">
13
+ <%= render(partial: "decidim/decidim_awesome/admin/config/autoedit_box_label", locals: { var: "scoped_styles", key: key, scope: "scoped_style_#{key}", delete_path: decidim_admin_decidim_awesome.scoped_style_path(key: key) }) %>
14
+ <p class="form-error is-visible" id="custom-style-error-<%= key %>"><%= errors[key.to_sym].join("<br>") if errors %></p>
18
15
  <%= text_area_tag key, value, name: "config[scoped_styles][#{key}]", rows: 5 %>
19
16
  <%= render(partial: "decidim/decidim_awesome/admin/config/constraints", locals: { key: "scoped_style_#{key}", constraints: constraints_for("scoped_style_#{key}") }) %>
20
17
  </div>
21
18
  <% end %>
22
19
 
23
- <%= link_to t(".new"), decidim_admin_decidim_awesome.new_scoped_style_path, method: :post %>
20
+ <%= link_to t("new", scope: "decidim.decidim_awesome.admin.config.form_scoped_styles"), decidim_admin_decidim_awesome.scoped_styles_path, method: :post %>
24
21
 
25
22
  <% end %>
26
23
  </div>
@@ -0,0 +1,4 @@
1
+ <%= admin_editor_for_proposal_body(form) %>
2
+ <div class="proposal_custom_field">
3
+ <div class="loading-spinner"></div>
4
+ </div>
@@ -0,0 +1,6 @@
1
+ <div class="proposal_custom_field" id="proposa-custom-field-<%= name %>" data-spec="<%= spec.to_json %>" data-name="<%= "#{form.object_name}[#{name}]" %>">
2
+ <div class="loading-spinner"></div>
3
+ </div>
4
+
5
+ <%= form.hidden_field name %>
6
+ <%= form.error_for name %>
@@ -54,7 +54,6 @@
54
54
  </div>
55
55
  </script>
56
56
 
57
- <%= stylesheet_link_tag "decidim/decidim_awesome/awesome_map/map" %>
58
57
  <style type="text/css">
59
58
  #map, .wrapper #map {
60
59
  height: <%= current_component.settings.map_height %>px;
@@ -69,5 +68,4 @@
69
68
  window.AwesomeMap = window.AwesomeMap || {};
70
69
  window.AwesomeMap.categories = <%= current_categories.to_json.html_safe %>;
71
70
  </script>
72
- <%= javascript_include_tag "decidim/decidim_awesome/awesome_map/map" %>
73
71
  <% end %>
@@ -0,0 +1,101 @@
1
+ <div class="card">
2
+ <div class="card-divider">
3
+ <h2 class="card-title"><%= title %></h2>
4
+ </div>
5
+
6
+ <div class="card-section">
7
+ <div class="row column hashtags__container">
8
+ <%= form.translated :text_field, :title, autofocus: true, class: "js-hashtags", hashtaggable: true %>
9
+ </div>
10
+
11
+ <div class="row column hashtags__container">
12
+ <%= render partial: "decidim/decidim_awesome/admin/proposals/editor", locals: { form: form } %>
13
+ </div>
14
+
15
+ <% if @form.component_automatic_hashtags.any? %>
16
+ <div class="field">
17
+ <%= form.label :automatic_hashtags %>
18
+ <div class="checkboxes hashtags">
19
+ <% @form.component_automatic_hashtags.each do |hashtag| %>
20
+ <label>
21
+ <%= check_box_tag "", "", { checked: true }, { disabled: true } %>#<%= hashtag %>
22
+ </label>
23
+ <% end %>
24
+ </div>
25
+ </div>
26
+ <% end %>
27
+
28
+ <% if @form.component_suggested_hashtags.any? %>
29
+ <div class="field">
30
+ <%= form.label :suggested_hashtags %>
31
+ <div class="checkboxes hashtags">
32
+ <%= form.collection_check_boxes :suggested_hashtags, @form.component_suggested_hashtags.map {|hashtag| [hashtag.downcase, "##{hashtag}"]}, :first, :last do |option|
33
+ option.label { option.check_box(checked: @form.suggested_hashtag_checked?(option.value)) + option.text }
34
+ end %>
35
+ </div>
36
+ </div>
37
+ <% end %>
38
+
39
+ <% if @form.meetings %>
40
+ <div class="meeting-fields">
41
+ <div class="row column">
42
+ <%= form.check_box :created_in_meeting, label: t(".created_in_meeting") %>
43
+ </div>
44
+
45
+ <div class="row column" id="proposal_meeting">
46
+ <%= form.select :meeting_id,
47
+ options_for_select(@form.meetings&.map { |meeting| [present(meeting).title, meeting.id] }, selected: meetings_as_authors_selected ),
48
+ { include_blank: true, label: t(".select_a_meeting") },
49
+ { multiple: false, class: "chosen-select" } %>
50
+ </div>
51
+ </div>
52
+ <% end %>
53
+
54
+ <% if @form.geocoding_enabled? %>
55
+ <div class="row column">
56
+ <%= form.geocoding_field :address %>
57
+ </div>
58
+ <% end %>
59
+
60
+ <% if @form.categories&.any? %>
61
+ <div class="row column">
62
+ <%= form.categories_select :category_id, @form.categories, include_blank: t(".select_a_category") %>
63
+ </div>
64
+ <% end %>
65
+
66
+ <% if current_component.has_subscopes? %>
67
+ <div class="row column">
68
+ <%= scopes_picker_field form, :scope_id, root: current_component.scope %>
69
+ </div>
70
+ <% end %>
71
+
72
+ <% if component_settings.attachments_allowed? %>
73
+ <%= render partial: "decidim/admin/shared/gallery", locals: { form: form } %>
74
+ <% end %>
75
+
76
+ <% if component_settings.attachments_allowed? %>
77
+ <div class="row column">
78
+ <fieldset>
79
+ <legend><%= t(".attachment_legend") %></legend>
80
+ <%= form.fields_for :attachment, @form.attachment do |form| %>
81
+ <div class="row column">
82
+ <%= form.text_field :title %>
83
+ </div>
84
+
85
+ <div class="row column">
86
+ <%= form.upload :file, optional: false %>
87
+ <% if params[:id].present? %>
88
+ <% if proposal.documents.present? %>
89
+ <%= form.hidden_field :id, value: proposal.documents.first.id %>
90
+ <%= form.check_box :delete_file, label: t(".delete_attachment"), value: proposal.documents.first.id %>
91
+ <% end %>
92
+ <% end %>
93
+ </div>
94
+ <% end %>
95
+ </fieldset>
96
+ </div>
97
+ <% end %>
98
+ </div>
99
+ </div>
100
+
101
+ <%= javascript_include_tag "decidim/proposals/admin/proposals_form" %>