decidim-core 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (194) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/config/decidim_core_manifest.js +1 -0
  3. data/app/assets/javascripts/decidim/notifications.js.es6 +33 -0
  4. data/app/assets/stylesheets/decidim/extras/_meeting-registrations.scss +11 -0
  5. data/app/assets/stylesheets/decidim/modules/_extra.scss +4 -0
  6. data/app/assets/stylesheets/decidim/modules/_process-nav.scss +14 -0
  7. data/app/commands/decidim/create_follow.rb +40 -0
  8. data/app/commands/decidim/create_omniauth_registration.rb +0 -2
  9. data/app/commands/decidim/create_registration.rb +1 -3
  10. data/app/commands/decidim/create_report.rb +7 -7
  11. data/app/commands/decidim/delete_follow.rb +37 -0
  12. data/app/commands/decidim/invite_user.rb +1 -3
  13. data/app/commands/decidim/update_notifications_settings.rb +1 -2
  14. data/app/constraints/decidim/current_feature.rb +3 -4
  15. data/app/controllers/concerns/decidim/settings.rb +1 -1
  16. data/app/controllers/decidim/features/base_controller.rb +5 -6
  17. data/app/controllers/decidim/follows_controller.rb +45 -0
  18. data/app/controllers/decidim/notifications_controller.rb +39 -0
  19. data/app/controllers/decidim/pages_controller.rb +2 -2
  20. data/app/controllers/decidim/scopes_controller.rb +2 -0
  21. data/app/controllers/decidim/widgets_controller.rb +3 -3
  22. data/app/forms/decidim/follow_form.rb +20 -0
  23. data/app/forms/decidim/invite_user_form.rb +1 -1
  24. data/app/forms/decidim/notifications_settings_form.rb +2 -4
  25. data/app/helpers/decidim/action_authorization_helper.rb +2 -1
  26. data/app/helpers/decidim/decidim_form_helper.rb +4 -0
  27. data/app/helpers/decidim/feature_path_helper.rb +2 -13
  28. data/app/helpers/decidim/icon_helper.rb +26 -8
  29. data/app/helpers/decidim/paginate_helper.rb +1 -1
  30. data/app/helpers/decidim/scopes_helper.rb +1 -1
  31. data/app/jobs/decidim/email_notification_generator_job.rb +12 -0
  32. data/app/jobs/decidim/export_job.rb +1 -3
  33. data/app/jobs/decidim/notification_generator_for_recipient_job.rb +14 -0
  34. data/app/jobs/decidim/notification_generator_job.rb +12 -0
  35. data/app/mailers/decidim/export_mailer.rb +6 -7
  36. data/app/mailers/decidim/notification_mailer.rb +20 -0
  37. data/app/mailers/decidim/reported_mailer.rb +3 -3
  38. data/app/models/decidim/abilities/admin_ability.rb +0 -1
  39. data/app/models/decidim/abilities/base_ability.rb +8 -0
  40. data/app/models/decidim/abilities/everyone_ability.rb +0 -2
  41. data/app/models/decidim/abilities/participatory_process_admin_ability.rb +1 -1
  42. data/app/models/decidim/abilities/participatory_process_collaborator_ability.rb +1 -1
  43. data/app/models/decidim/category.rb +4 -4
  44. data/app/models/decidim/feature.rb +29 -4
  45. data/app/models/decidim/follow.rb +10 -0
  46. data/app/models/decidim/moderation.rb +1 -1
  47. data/app/models/decidim/notification.rb +12 -0
  48. data/app/models/decidim/scope.rb +8 -8
  49. data/app/models/decidim/user.rb +11 -1
  50. data/app/presenters/decidim/home_stats_presenter.rb +1 -1
  51. data/app/presenters/decidim/resource_locator_presenter.rb +3 -18
  52. data/app/queries/decidim/participatory_processes_with_user_role.rb +1 -1
  53. data/app/services/decidim/email_notification_generator.rb +63 -0
  54. data/app/services/decidim/events_manager.rb +41 -0
  55. data/app/services/decidim/notification_generator.rb +51 -0
  56. data/app/services/decidim/notification_generator_for_recipient.rb +50 -0
  57. data/app/uploaders/decidim/attachment_uploader.rb +1 -1
  58. data/app/views/decidim/authorizations/first_login.html.erb +2 -2
  59. data/app/views/decidim/follows/update_button.js.erb +3 -0
  60. data/app/views/decidim/notification_mailer/event_received.html.erb +9 -0
  61. data/app/views/decidim/notifications/_notification.html.erb +18 -0
  62. data/app/views/decidim/notifications/index.html.erb +32 -0
  63. data/app/views/decidim/notifications_settings/show.html.erb +3 -10
  64. data/app/views/decidim/shared/_follow_button.html.erb +19 -0
  65. data/app/views/layouts/decidim/_head.html.erb +1 -0
  66. data/app/views/layouts/decidim/_head_extra.html.erb +7 -0
  67. data/app/views/layouts/decidim/_user_menu.html.erb +1 -0
  68. data/app/views/layouts/decidim/_wrapper.html.erb +3 -0
  69. data/app/views/layouts/decidim/widget.html.erb +3 -3
  70. data/app/views/pages/home/_hero.html.erb +1 -1
  71. data/app/views/pages/home/_highlighted_processes.html.erb +3 -3
  72. data/config/locales/ca.yml +29 -74
  73. data/config/locales/en.yml +23 -71
  74. data/config/locales/es.yml +31 -78
  75. data/config/locales/eu.yml +61 -65
  76. data/config/locales/fi.yml +91 -51
  77. data/config/locales/fr.yml +40 -83
  78. data/config/locales/it.yml +129 -54
  79. data/config/locales/nl.yml +90 -51
  80. data/config/locales/pl.yml +319 -10
  81. data/config/locales/uk.yml +400 -0
  82. data/config/routes.rb +8 -14
  83. data/db/migrate/20170720120231_make_moderations_polymorphic.rb +29 -0
  84. data/db/migrate/20170726145242_make_categories_polymorphic.rb +27 -0
  85. data/db/migrate/20170807123535_create_decidim_follows.rb +20 -0
  86. data/db/migrate/20170808071019_create_decidim_notifications.rb +13 -0
  87. data/db/migrate/20170906091718_add_extra_to_notifications.rb +7 -0
  88. data/db/migrate/20170912082054_add_emails_on_notifications_flag_to_user.rb +7 -0
  89. data/db/migrate/20170913092351_add_header_snippets_to_organizations.rb +7 -0
  90. data/db/migrate/20170914075721_remove_followable_index_from_follows.rb +7 -0
  91. data/db/migrate/20170914092116_remove_comment_and_replies_notifications_from_users.rb +8 -0
  92. data/db/seeds.rb +2 -108
  93. data/lib/decidim/core.rb +46 -8
  94. data/lib/decidim/core/engine.rb +20 -6
  95. data/lib/decidim/core/test.rb +3 -0
  96. data/lib/decidim/core/test/factories.rb +37 -75
  97. data/lib/decidim/core/test/shared_examples/comments_examples.rb +0 -26
  98. data/lib/decidim/core/test/shared_examples/follows_examples.rb +37 -0
  99. data/lib/decidim/core/test/shared_examples/manage_moderations_examples.rb +1 -1
  100. data/lib/decidim/core/test/shared_examples/process_announcements_examples.rb +1 -1
  101. data/lib/decidim/core/test/shared_examples/reportable.rb +4 -4
  102. data/lib/decidim/core/test/shared_examples/reports_examples.rb +1 -1
  103. data/lib/decidim/core/test/shared_examples/scope_helper_examples.rb +41 -0
  104. data/lib/decidim/core/test/shared_examples/user_localised_email_examples.rb +25 -0
  105. data/lib/decidim/core/version.rb +1 -1
  106. data/lib/decidim/engine_router.rb +54 -0
  107. data/lib/decidim/events.rb +9 -0
  108. data/lib/decidim/events/base_event.rb +70 -0
  109. data/lib/decidim/events/email_event.rb +39 -0
  110. data/lib/decidim/events/notification_event.rb +32 -0
  111. data/lib/decidim/exporters.rb +7 -0
  112. data/lib/decidim/exporters/export_data.rb +14 -0
  113. data/lib/decidim/feature_manifest.rb +2 -2
  114. data/lib/decidim/features/namer.rb +1 -1
  115. data/lib/decidim/followable.rb +13 -0
  116. data/lib/decidim/form_builder.rb +1 -1
  117. data/lib/decidim/has_feature.rb +1 -1
  118. data/lib/decidim/has_settings.rb +19 -15
  119. data/lib/decidim/manifest_registry.rb +1 -3
  120. data/lib/decidim/participable.rb +80 -0
  121. data/lib/decidim/participatory_space_manifest.rb +40 -0
  122. data/lib/decidim/query_extensions.rb +1 -1
  123. data/lib/decidim/resource_manifest.rb +1 -1
  124. data/lib/decidim/settings_manifest.rb +0 -4
  125. data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.uk.js +14 -0
  126. data/vendor/assets/javascripts/morphdom.js +14 -5
  127. metadata +70 -79
  128. data/app/assets/images/decidim/process.svg +0 -10
  129. data/app/constraints/decidim/current_participatory_process.rb +0 -35
  130. data/app/controllers/concerns/decidim/needs_participatory_process.rb +0 -46
  131. data/app/controllers/decidim/participatory_process_groups_controller.rb +0 -26
  132. data/app/controllers/decidim/participatory_process_steps_controller.rb +0 -18
  133. data/app/controllers/decidim/participatory_process_widgets_controller.rb +0 -19
  134. data/app/controllers/decidim/participatory_processes_controller.rb +0 -49
  135. data/app/helpers/decidim/participatory_process_helper.rb +0 -17
  136. data/app/helpers/decidim/participatory_process_steps_helper.rb +0 -18
  137. data/app/models/decidim/participatory_process.rb +0 -61
  138. data/app/models/decidim/participatory_process_group.rb +0 -15
  139. data/app/models/decidim/participatory_process_step.rb +0 -39
  140. data/app/presenters/decidim/participatory_process_stats_presenter.rb +0 -50
  141. data/app/queries/decidim/highlighted_participatory_processes.rb +0 -10
  142. data/app/queries/decidim/organization_participatory_process_groups.rb +0 -14
  143. data/app/queries/decidim/organization_participatory_processes.rb +0 -14
  144. data/app/queries/decidim/organization_prioritized_participatory_processes.rb +0 -18
  145. data/app/queries/decidim/organization_published_participatory_processes.rb +0 -17
  146. data/app/queries/decidim/prioritized_participatory_processes.rb +0 -11
  147. data/app/queries/decidim/promoted_participatory_processes.rb +0 -10
  148. data/app/queries/decidim/published_participatory_processes.rb +0 -10
  149. data/app/views/decidim/participatory_process_groups/_participatory_process_group.html.erb +0 -22
  150. data/app/views/decidim/participatory_process_groups/show.html.erb +0 -11
  151. data/app/views/decidim/participatory_process_steps/_participatory_process_step.html.erb +0 -16
  152. data/app/views/decidim/participatory_process_steps/_timeline.html.erb +0 -7
  153. data/app/views/decidim/participatory_process_steps/index.html.erb +0 -14
  154. data/app/views/decidim/participatory_process_widgets/show.html.erb +0 -17
  155. data/app/views/decidim/participatory_processes/_no_processes_yet.html.erb +0 -3
  156. data/app/views/decidim/participatory_processes/_order_by_processes.html.erb +0 -3
  157. data/app/views/decidim/participatory_processes/_participatory_process.html.erb +0 -28
  158. data/app/views/decidim/participatory_processes/_promoted_process.html.erb +0 -32
  159. data/app/views/decidim/participatory_processes/_statistics.html.erb +0 -10
  160. data/app/views/decidim/participatory_processes/index.html.erb +0 -17
  161. data/app/views/decidim/participatory_processes/show.html.erb +0 -85
  162. data/app/views/layouts/decidim/_process_header.html.erb +0 -65
  163. data/app/views/layouts/decidim/_process_header_steps.html.erb +0 -27
  164. data/app/views/layouts/decidim/participatory_process.html.erb +0 -30
  165. data/config/i18n-tasks.yml +0 -138
  166. data/db/migrate/20161005130108_add_participatory_processes.rb +0 -19
  167. data/db/migrate/20161010102356_translate_processes.rb +0 -17
  168. data/db/migrate/20161011125616_add_hero_image_to_processes.rb +0 -7
  169. data/db/migrate/20161011141033_add_banner_image_to_processes.rb +0 -7
  170. data/db/migrate/20161013134732_add_promoted_flag_to_processes.rb +0 -7
  171. data/db/migrate/20161017085822_add_participatory_process_steps.rb +0 -18
  172. data/db/migrate/20161019072016_add_active_flag_to_step.rb +0 -13
  173. data/db/migrate/20161020080756_add_position_to_steps.rb +0 -9
  174. data/db/migrate/20161025125300_add_published_at_to_processes.rb +0 -7
  175. data/db/migrate/20161107152228_remove_not_null_on_step_position.rb +0 -7
  176. data/db/migrate/20161110092735_add_index_for_process_slug_organization.rb +0 -10
  177. data/db/migrate/20161116115156_create_attachments.rb +0 -18
  178. data/db/migrate/20170116135237_loosen_step_requirements.rb +0 -8
  179. data/db/migrate/20170123134023_make_attachments_polymorphic.rb +0 -20
  180. data/db/migrate/20170125135937_rename_attachable_to_attached_to.rb +0 -13
  181. data/db/migrate/20170126151123_add_extra_info_to_processes.rb +0 -10
  182. data/db/migrate/20170206083118_rename_extra_info_on_processes.rb +0 -14
  183. data/db/migrate/20170220110740_remove_steps_short_description.rb +0 -23
  184. data/db/migrate/20170221094835_add_scopes_to_processes.rb +0 -8
  185. data/db/migrate/20170228142440_add_participatory_process_groups.rb +0 -17
  186. data/db/migrate/20170404132616_change_steps_end_and_start_date_to_date.rb +0 -8
  187. data/db/migrate/20170725085104_add_show_statistics_to_participatory_processes.rb +0 -7
  188. data/db/migrate/20170804125402_attachment_description_nullable.rb +0 -7
  189. data/db/migrate/20170808080905_add_announcement_to_participatory_processes.rb +0 -7
  190. data/db/migrate/20170809084005_add_scopes_enabled_to_participatory_processes.rb +0 -7
  191. data/db/seeds/Exampledocument.pdf +0 -0
  192. data/db/seeds/city.jpeg +0 -0
  193. data/db/seeds/city2.jpeg +0 -0
  194. data/lib/decidim/notifiable.rb +0 -22
@@ -3,6 +3,8 @@
3
3
  module Decidim
4
4
  # Exposes the scopes text search so users can choose a scope writing its name.
5
5
  class ScopesController < Decidim::ApplicationController
6
+ skip_before_action :store_current_location
7
+
6
8
  def search
7
9
  authorize! :search, Scope
8
10
  root = Scope.where(id: params[:root], organization: current_organization).first
@@ -8,7 +8,7 @@ module Decidim
8
8
 
9
9
  layout "decidim/widget"
10
10
 
11
- helper_method :model, :iframe_url, :current_participatory_process
11
+ helper_method :model, :iframe_url, :current_participatory_space
12
12
 
13
13
  def show
14
14
  respond_to do |format|
@@ -19,8 +19,8 @@ module Decidim
19
19
 
20
20
  private
21
21
 
22
- def current_participatory_process
23
- @current_participatory_process ||= model.feature.participatory_process
22
+ def current_participatory_space
23
+ @current_participatory_space ||= model.feature.participatory_space
24
24
  end
25
25
 
26
26
  def iframe_url
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ # A form object to be used when users want to follow a followable resource.
5
+ class FollowForm < Decidim::Form
6
+ mimic :follow
7
+
8
+ attribute :followable_gid, String
9
+
10
+ validates :followable_gid, :followable, presence: true
11
+
12
+ def followable
13
+ @followable ||= GlobalID::Locator.locate_signed followable_gid
14
+ end
15
+
16
+ def follow
17
+ @follow ||= Decidim::Follow.where(user: current_user, followable: followable).first
18
+ end
19
+ end
20
+ end
@@ -33,7 +33,7 @@ module Decidim
33
33
  def available_roles_for_select
34
34
  Decidim::User::ROLES.map do |role|
35
35
  [
36
- I18n.t(role, scope: "decidim.admin.models.user.fields.roles"),
36
+ I18n.t("models.user.fields.roles.#{role}", scope: "decidim.admin"),
37
37
  role
38
38
  ]
39
39
  end
@@ -6,12 +6,10 @@ module Decidim
6
6
  class NotificationsSettingsForm < Form
7
7
  mimic :user
8
8
 
9
- attribute :comments_notifications
10
- attribute :replies_notifications
9
+ attribute :email_on_notification
11
10
  attribute :newsletter_notifications
12
11
 
13
- validates :comments_notifications, presence: true
14
- validates :replies_notifications, presence: true
12
+ validates :email_on_notification, presence: true
15
13
  validates :newsletter_notifications, presence: true
16
14
  end
17
15
  end
@@ -67,11 +67,12 @@ module Decidim
67
67
  end
68
68
 
69
69
  unless current_user_authorized?(action)
70
- html_options["onclick"] = "event.preventDefault();"
71
70
  html_options["data-toggle"] = current_user ? "#{action.to_s.underscore}AuthorizationModal" : "loginModal"
72
71
  url = ""
73
72
  end
74
73
 
74
+ html_options["onclick"] = "event.preventDefault();" if url == ""
75
+
75
76
  if block_given?
76
77
  button_to(url, html_options, &body)
77
78
  else
@@ -13,6 +13,10 @@ module Decidim
13
13
  def decidim_form_for(record, options = {}, &block)
14
14
  options[:data] ||= {}
15
15
  options[:data].update(abide: true, "live-validate" => true, "validate-on-blur" => true)
16
+
17
+ options[:html] ||= {}
18
+ options[:html].update(novalidate: true)
19
+
16
20
  form_for(record, options, &block)
17
21
  end
18
22
 
@@ -9,7 +9,7 @@ module Decidim
9
9
  #
10
10
  # Returns a url.
11
11
  def main_feature_path(feature)
12
- feature_root_path_for(feature.manifest.engine, feature)
12
+ EngineRouter.main_proxy(feature).root_path
13
13
  end
14
14
 
15
15
  # Returns the defined admin root path for a given feature.
@@ -18,18 +18,7 @@ module Decidim
18
18
  #
19
19
  # Returns a url.
20
20
  def manage_feature_path(feature)
21
- feature_root_path_for(feature.manifest.admin_engine, feature)
22
- end
23
-
24
- private
25
-
26
- def feature_root_path_for(engine, feature)
27
- url_params = {
28
- feature_id: feature.id,
29
- participatory_process_id: feature.participatory_process.id
30
- }
31
-
32
- engine.routes.url_helpers.root_path(url_params)
21
+ EngineRouter.admin_proxy(feature).root_path
33
22
  end
34
23
  end
35
24
  end
@@ -7,23 +7,41 @@ module Decidim
7
7
  # a question mark when no icon is found.
8
8
  #
9
9
  # feature - The feature to generate the icon for.
10
+ # options - a Hash with options
10
11
  #
11
12
  # Returns an HTML tag with the icon.
12
- def feature_icon(feature)
13
- feature_manifest_icon(feature.manifest)
13
+ def feature_icon(feature, options = {})
14
+ manifest_icon(feature.manifest, options)
14
15
  end
15
16
 
16
- # Public: Returns an icon given an instance of a Feature Manifest. It defaults to
17
+ # Public: Returns an icon given an instance of a Manifest. It defaults to
17
18
  # a question mark when no icon is found.
18
19
  #
19
- # feature_manifest - The feature manifest to generate the icon for.
20
+ # manifest - The manifest to generate the icon for.
21
+ # options - a Hash with options
20
22
  #
21
23
  # Returns an HTML tag with the icon.
22
- def feature_manifest_icon(feature_manifest)
23
- if feature_manifest.icon
24
- external_icon feature_manifest.icon
24
+ def manifest_icon(manifest, options = {})
25
+ if manifest.icon
26
+ external_icon manifest.icon, options
25
27
  else
26
- icon "question-mark"
28
+ icon "question-mark", options
29
+ end
30
+ end
31
+
32
+ # Public: Finds the correct icon for the given resource. If the resource has a
33
+ # Feature then it uses it to find the icon, otherwise checks for the resource
34
+ # manifest to find the icon.
35
+ #
36
+ # resource - The resource to generate the icon for.
37
+ # options - a Hash with options
38
+ #
39
+ # Returns an HTML tag with the icon.
40
+ def resource_icon(resource, options = {})
41
+ if resource.respond_to?(:feature)
42
+ feature_icon(resource.feature, options)
43
+ else
44
+ manifest_icon(resource.manifest, options)
27
45
  end
28
46
  end
29
47
  end
@@ -8,7 +8,7 @@ module Decidim
8
8
  #
9
9
  # collection - a collection of elements that need to be paginated
10
10
  # paginate_params - a Hash with options to delegate to the pagination helper.
11
- def decidim_paginate(collection, paginate_params)
11
+ def decidim_paginate(collection, paginate_params = {})
12
12
  # Kaminari uses url_for to generate the url, but this doesn't play nice with our engine system
13
13
  # and unless we remove these params they are added again as query string :(
14
14
  default_params = {
@@ -9,7 +9,7 @@ module Decidim
9
9
  #
10
10
  # Returns boolean.
11
11
  def has_visible_scopes?(resource)
12
- current_participatory_process.scopes_enabled? && !current_participatory_process.scope.present? && resource.scope.present?
12
+ current_participatory_space.scopes_enabled? && !current_participatory_space.scope.present? && resource.scope.present?
13
13
  end
14
14
  end
15
15
  end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ class EmailNotificationGeneratorJob < ApplicationJob
5
+ queue_as :decidim_events
6
+
7
+ def perform(event, event_class_name, resource, recipient_ids, extra)
8
+ event_class = event_class_name.constantize
9
+ EmailNotificationGenerator.new(event, event_class, resource, recipient_ids, extra).generate
10
+ end
11
+ end
12
+ end
@@ -12,9 +12,7 @@ module Decidim
12
12
  collection = export_manifest.collection.call(feature)
13
13
  serializer = export_manifest.serializer
14
14
 
15
- export_data = Decidim::Exporters.const_get(format.upcase).new(collection, serializer).export
16
-
17
- name = "#{name}-#{I18n.localize(Date.today, format: :default)}-#{Time.now.seconds_since_midnight.to_i}"
15
+ export_data = Decidim::Exporters.find_exporter(format).new(collection, serializer).export
18
16
 
19
17
  ExportMailer.export(user, name, export_data).deliver_now
20
18
  end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ class NotificationGeneratorForRecipientJob < ApplicationJob
5
+ queue_as :decidim_events
6
+
7
+ def perform(event, event_class_name, resource, recipient_id, extra)
8
+ event_class = event_class_name.constantize
9
+ NotificationGeneratorForRecipient
10
+ .new(event, event_class, resource, recipient_id, extra)
11
+ .generate
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ class NotificationGeneratorJob < ApplicationJob
5
+ queue_as :decidim_events
6
+
7
+ def perform(event, event_class_name, resource, recipient_ids, extra)
8
+ event_class = event_class_name.constantize
9
+ NotificationGenerator.new(event, event_class, resource, recipient_ids, extra).generate
10
+ end
11
+ end
12
+ end
@@ -8,22 +8,21 @@ module Decidim
8
8
  # zipped file.
9
9
  #
10
10
  # user - The user to be notified.
11
- # name - The name of the export.
11
+ # export_name - The name of the export.
12
12
  # export_data - The data containing the result of the export.
13
13
  #
14
14
  # Returns nothing.
15
- def export(user, name, export_data)
15
+ def export(user, export_name, export_data)
16
16
  @user = user
17
17
  @organization = user.organization
18
18
 
19
- original_file_name = "#{name}.#{export_data.extension}"
19
+ filename = export_data.filename(export_name)
20
+ filename_without_extension = export_data.filename(export_name, extension: false)
20
21
 
21
- attachments["#{name}.zip"] = FileZipper.new(
22
- original_file_name, export_data.read
23
- ).zip
22
+ attachments["#{filename_without_extension}.zip"] = FileZipper.new(filename, export_data.read).zip
24
23
 
25
24
  with_user(user) do
26
- mail(to: "#{user.name} <#{user.email}>", subject: I18n.t("decidim.export_mailer.subject", name: original_file_name))
25
+ mail(to: "#{user.name} <#{user.email}>", subject: I18n.t("decidim.export_mailer.subject", name: filename))
27
26
  end
28
27
  end
29
28
  end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ # A custom mailer for sending notifications to users when
5
+ # a events are received.
6
+ class NotificationMailer < Decidim::ApplicationMailer
7
+ helper Decidim::ResourceHelper
8
+
9
+ def event_received(event, event_class_name, resource, user, extra)
10
+ with_user(user) do
11
+ @organization = resource.organization
12
+ event_class = event_class_name.constantize
13
+ @event_instance = event_class.new(resource: resource, event_name: event, user: user, extra: extra)
14
+ subject = @event_instance.email_subject
15
+
16
+ mail(to: user.email, subject: subject)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -10,7 +10,7 @@ module Decidim
10
10
  def report(user, report)
11
11
  with_user(user) do
12
12
  @report = report
13
- @participatory_process = @report.moderation.participatory_process
13
+ @participatory_space = @report.moderation.participatory_space
14
14
  @organization = user.organization
15
15
  @user = user
16
16
  subject = I18n.t("report.subject", scope: "decidim.reported_mailer")
@@ -21,7 +21,7 @@ module Decidim
21
21
  def hide(user, report)
22
22
  with_user(user) do
23
23
  @report = report
24
- @participatory_process = @report.moderation.participatory_process
24
+ @participatory_space = @report.moderation.participatory_space
25
25
  @organization = user.organization
26
26
  @user = user
27
27
  subject = I18n.t("hide.subject", scope: "decidim.reported_mailer")
@@ -36,7 +36,7 @@ module Decidim
36
36
  end
37
37
 
38
38
  def manage_moderations_url
39
- @manage_moderations_url ||= decidim_admin.moderations_url(@participatory_process.id, host: @organization.host)
39
+ @manage_moderations_url ||= EngineRouter.admin_proxy(@participatory_space).moderations_url(host: @organization.host)
40
40
  end
41
41
  end
42
42
  end
@@ -17,7 +17,6 @@ module Decidim
17
17
 
18
18
  def define_abilities
19
19
  can :read, :admin_dashboard
20
- can :read, ParticipatoryProcess
21
20
  can :read, Feature
22
21
  can :impersonate, :managed_users
23
22
  end
@@ -28,6 +28,14 @@ module Decidim
28
28
  can :manage, Authorization do |authorization|
29
29
  authorization.user == user
30
30
  end
31
+
32
+ can :manage, Follow do |follow|
33
+ follow.user == user
34
+ end
35
+
36
+ can :manage, Notification do |notification|
37
+ notification.user == user
38
+ end
31
39
  end
32
40
  end
33
41
  end
@@ -8,8 +8,6 @@ module Decidim
8
8
  include CanCan::Ability
9
9
 
10
10
  def initialize(user, _context)
11
- can :read, ParticipatoryProcessGroup
12
- can :read, ParticipatoryProcess, &:published?
13
11
  can :read, :public_pages
14
12
  can :manage, :locales
15
13
 
@@ -20,7 +20,7 @@ module Decidim
20
20
  end
21
21
 
22
22
  can :read, Feature do |feature|
23
- can_manage_process?(feature.participatory_process)
23
+ can_manage_process?(feature.participatory_space)
24
24
  end
25
25
  end
26
26
  end
@@ -20,7 +20,7 @@ module Decidim
20
20
  end
21
21
 
22
22
  can :read, Feature do |feature|
23
- can_manage_process?(feature.participatory_process)
23
+ can_manage_process?(feature.participatory_space)
24
24
  end
25
25
  end
26
26
  end
@@ -4,13 +4,13 @@ module Decidim
4
4
  # Categories serve as a taxonomy for components to use for while in the
5
5
  # context of a participatory process.
6
6
  class Category < ApplicationRecord
7
- belongs_to :participatory_process, foreign_key: "decidim_participatory_process_id", class_name: "Decidim::ParticipatoryProcess", inverse_of: :categories
7
+ belongs_to :participatory_space, foreign_key: "decidim_participatory_space_id", foreign_type: "decidim_participatory_space_type", polymorphic: true
8
8
  has_many :subcategories, foreign_key: "parent_id", class_name: "Decidim::Category", dependent: :destroy, inverse_of: :parent
9
9
  belongs_to :parent, class_name: "Decidim::Category", foreign_key: "parent_id", inverse_of: :subcategories, optional: true
10
10
  has_many :categorizations, foreign_key: "decidim_category_id", class_name: "Decidim::Categorization", dependent: :destroy
11
11
 
12
12
  validate :forbid_deep_nesting
13
- before_validation :subcategories_have_same_process
13
+ before_validation :subcategories_have_same_participatory_space
14
14
 
15
15
  # Scope to return only the first-class categories, that is, those that are
16
16
  # not subcategories.
@@ -33,9 +33,9 @@ module Decidim
33
33
  errors.add(:parent_id, :nesting_too_deep)
34
34
  end
35
35
 
36
- def subcategories_have_same_process
36
+ def subcategories_have_same_participatory_space
37
37
  return unless parent
38
- self.participatory_process = parent.participatory_process
38
+ self.participatory_space = parent.participatory_space
39
39
  end
40
40
  end
41
41
  end
@@ -8,13 +8,13 @@ module Decidim
8
8
  include HasSettings
9
9
  include Publicable
10
10
 
11
- belongs_to :participatory_process, foreign_key: "decidim_participatory_process_id"
12
- has_one :organization, through: :participatory_process
13
- has_many :categories, through: :participatory_process
14
- has_many :scopes, through: :organization
11
+ belongs_to :participatory_space, polymorphic: true
15
12
 
16
13
  default_scope { order(arel_table[:weight].asc) }
17
14
 
15
+ delegate :organization, :categories, to: :participatory_space
16
+ delegate :scopes, to: :organization
17
+
18
18
  # Public: Finds the manifest this feature is associated to.
19
19
  #
20
20
  # Returns a FeatureManifest.
@@ -31,9 +31,34 @@ module Decidim
31
31
  self.manifest_name = manifest.name
32
32
  end
33
33
 
34
+ # Public: The name of the engine the feature is mounted to.
35
+ def mounted_engine
36
+ "decidim_#{participatory_space_name}_#{manifest_name}"
37
+ end
38
+
39
+ # Public: The name of the admin engine the feature is mounted to.
40
+ def mounted_admin_engine
41
+ "decidim_admin_#{participatory_space_name}_#{manifest_name}"
42
+ end
43
+
44
+ # Public: The hash of contextual params when the feature is mounted.
45
+ def mounted_params
46
+ {
47
+ host: organization.host,
48
+ feature_id: id,
49
+ participatory_space.foreign_key.to_sym => participatory_space.id
50
+ }
51
+ end
52
+
34
53
  # Public: Returns the value of the registered primary stat.
35
54
  def primary_stat
36
55
  @primary_stat ||= manifest.stats.filter(primary: true).with_context([self]).map { |name, value| [name, value] }.first&.last
37
56
  end
57
+
58
+ private
59
+
60
+ def participatory_space_name
61
+ participatory_space.underscored_name
62
+ end
38
63
  end
39
64
  end