decidim-initiatives 0.29.2 → 0.30.0.rc2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. checksums.yaml +4 -4
  2. data/app/cells/decidim/initiatives/content_blocks/highlighted_initiatives_settings_form/show.erb +1 -1
  3. data/app/commands/decidim/initiatives/create_initiative.rb +16 -4
  4. data/app/commands/decidim/initiatives/update_initiative.rb +23 -9
  5. data/app/controllers/concerns/decidim/initiatives/needs_initiative.rb +1 -1
  6. data/app/controllers/decidim/initiatives/admin/application_controller.rb +2 -0
  7. data/app/controllers/decidim/initiatives/admin/component_share_tokens_controller.rb +18 -0
  8. data/app/controllers/decidim/initiatives/admin/initiative_share_tokens_controller.rb +18 -0
  9. data/app/controllers/decidim/initiatives/admin/initiatives_controller.rb +8 -8
  10. data/app/controllers/decidim/initiatives/create_initiative_controller.rb +3 -2
  11. data/app/controllers/decidim/initiatives/initiative_types_controller.rb +1 -1
  12. data/app/controllers/decidim/initiatives/initiatives_controller.rb +3 -0
  13. data/app/forms/decidim/initiatives/admin/initiative_answer_form.rb +1 -1
  14. data/app/forms/decidim/initiatives/vote_form.rb +1 -1
  15. data/app/helpers/decidim/initiatives/initiative_helper.rb +1 -39
  16. data/app/helpers/decidim/initiatives/initiatives_helper.rb +8 -5
  17. data/app/helpers/decidim/initiatives/scopes_helper.rb +43 -0
  18. data/app/jobs/decidim/initiatives/export_initiatives_job.rb +5 -1
  19. data/app/models/decidim/initiative.rb +40 -27
  20. data/app/models/decidim/initiatives_type_scope.rb +9 -0
  21. data/app/permissions/decidim/initiatives/admin/permissions.rb +7 -0
  22. data/app/permissions/decidim/initiatives/permissions.rb +10 -3
  23. data/app/queries/decidim/initiatives/outdated_validating_initiatives.rb +1 -1
  24. data/app/queries/decidim/initiatives/support_period_finished_initiatives.rb +2 -2
  25. data/app/serializers/decidim/initiatives/download_your_data_initiative_serializer.rb +15 -0
  26. data/app/serializers/decidim/initiatives/initiative_serializer.rb +5 -24
  27. data/app/serializers/decidim/initiatives/open_data_initiative_serializer.rb +54 -0
  28. data/app/services/decidim/initiatives/data_encryptor.rb +1 -1
  29. data/app/services/decidim/initiatives/pdf_signature_example.rb +0 -2
  30. data/app/views/decidim/initiatives/admin/initiatives/edit.html.erb +1 -2
  31. data/app/views/decidim/initiatives/admin/initiatives/index.html.erb +7 -0
  32. data/app/views/decidim/initiatives/committee_requests/new.html.erb +1 -2
  33. data/app/views/decidim/initiatives/create_initiative/fill_data.html.erb +3 -3
  34. data/app/views/decidim/initiatives/create_initiative/select_initiative_type.html.erb +10 -2
  35. data/app/views/decidim/initiatives/initiatives/_form.html.erb +3 -3
  36. data/app/views/decidim/initiatives/initiatives/_new_initiative_button.html.erb +16 -13
  37. data/app/views/decidim/initiatives/initiatives/_vote_button.html.erb +9 -3
  38. data/app/views/decidim/initiatives/initiatives/_vote_cabin.html.erb +0 -1
  39. data/app/views/decidim/initiatives/initiatives/show.html.erb +7 -8
  40. data/app/views/layouts/decidim/admin/_manage_initiatives.html.erb +11 -0
  41. data/app/views/layouts/decidim/admin/initiatives.html.erb +1 -9
  42. data/config/assets.rb +1 -3
  43. data/config/locales/ar.yml +7 -8
  44. data/config/locales/bg.yml +2 -22
  45. data/config/locales/ca.yml +55 -21
  46. data/config/locales/cs.yml +55 -21
  47. data/config/locales/de.yml +55 -21
  48. data/config/locales/el.yml +2 -9
  49. data/config/locales/en.yml +53 -19
  50. data/config/locales/es-MX.yml +55 -21
  51. data/config/locales/es-PY.yml +55 -21
  52. data/config/locales/es.yml +55 -21
  53. data/config/locales/eu.yml +55 -21
  54. data/config/locales/fi-plain.yml +55 -21
  55. data/config/locales/fi.yml +55 -21
  56. data/config/locales/fr-CA.yml +9 -22
  57. data/config/locales/fr.yml +9 -22
  58. data/config/locales/ga-IE.yml +0 -3
  59. data/config/locales/gl.yml +2 -10
  60. data/config/locales/hu.yml +2 -20
  61. data/config/locales/id-ID.yml +2 -8
  62. data/config/locales/is-IS.yml +0 -9
  63. data/config/locales/it.yml +2 -11
  64. data/config/locales/ja.yml +55 -21
  65. data/config/locales/lb.yml +2 -7
  66. data/config/locales/lt.yml +2 -22
  67. data/config/locales/lv.yml +2 -9
  68. data/config/locales/nl.yml +2 -11
  69. data/config/locales/no.yml +2 -13
  70. data/config/locales/pl.yml +2 -21
  71. data/config/locales/pt-BR.yml +2 -27
  72. data/config/locales/pt.yml +2 -11
  73. data/config/locales/ro-RO.yml +2 -19
  74. data/config/locales/ru.yml +0 -9
  75. data/config/locales/sk.yml +2 -8
  76. data/config/locales/sl.yml +0 -1
  77. data/config/locales/sv.yml +13 -21
  78. data/config/locales/tr-TR.yml +2 -11
  79. data/config/locales/uk.yml +0 -9
  80. data/config/locales/zh-CN.yml +2 -10
  81. data/config/locales/zh-TW.yml +2 -21
  82. data/db/migrate/20241127104718_add_taxonomy_to_initiatives_type_scope.rb +7 -0
  83. data/decidim-initiatives.gemspec +1 -3
  84. data/lib/decidim/api/initiative_api_type.rb +9 -10
  85. data/lib/decidim/api/initiative_committee_member_type.rb +3 -4
  86. data/lib/decidim/api/initiative_type.rb +15 -21
  87. data/lib/decidim/api/initiative_type_interface.rb +1 -5
  88. data/lib/decidim/exporters/initiative_votes_pdf.rb +163 -0
  89. data/lib/decidim/initiatives/admin_engine.rb +68 -49
  90. data/lib/decidim/initiatives/application_form_pdf.rb +181 -0
  91. data/lib/decidim/initiatives/engine.rb +6 -0
  92. data/lib/decidim/initiatives/menu.rb +8 -0
  93. data/lib/decidim/initiatives/participatory_space.rb +8 -1
  94. data/lib/decidim/initiatives/test/factories.rb +5 -8
  95. data/lib/decidim/initiatives/version.rb +1 -1
  96. data/lib/decidim/initiatives.rb +7 -1
  97. metadata +25 -59
  98. data/app/cells/decidim/initiatives_votes/vote/show.erb +0 -39
  99. data/app/cells/decidim/initiatives_votes/vote_cell.rb +0 -58
  100. data/app/packs/entrypoints/decidim_initiatives_initiatives_votes.js +0 -1
  101. data/app/packs/entrypoints/decidim_initiatives_initiatives_votes.scss +0 -1
  102. data/app/packs/entrypoints/decidim_initiatives_print.js +0 -1
  103. data/app/packs/entrypoints/decidim_initiatives_print.scss +0 -1
  104. data/app/packs/stylesheets/decidim/initiatives/initiatives-votes.scss +0 -96
  105. data/app/packs/stylesheets/decidim/initiatives/print-initiative.scss +0 -172
  106. data/app/views/decidim/initiatives/admin/initiatives/_signatures.html.erb +0 -87
  107. data/app/views/decidim/initiatives/admin/initiatives/export_pdf_signatures.html.erb +0 -8
  108. data/app/views/decidim/initiatives/admin/initiatives/export_pdf_signatures.pdf.erb +0 -5
  109. data/app/views/decidim/initiatives/initiatives/_linked_initiatives.html.erb +0 -0
  110. data/app/views/decidim/initiatives/initiatives/print.html.erb +0 -161
  111. data/app/views/layouts/decidim/admin/initiatives_votes.pdf.erb +0 -11
  112. data/config/initializers/wicked_pdf.rb +0 -22
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d8aacccca0a9af81f8679c37857ac40b7a234f19389a985c2e9a93f59fad2e8d
4
- data.tar.gz: d776e653fbbbaf9a998ecff7fa3de3ac3829f0d9ee7541f30de19fd4dd2839ed
3
+ metadata.gz: f90504381ebe755e6f08ded7a9b42f3438267ee8df1c8ee8869342589c363daf
4
+ data.tar.gz: 37451af643dcb1e05855aa2c74c5242fba6b9fb5f9d1fee56a64ff1163cdded6
5
5
  SHA512:
6
- metadata.gz: 3e2f88c9f09a43805b7ecccc618702671c6d9797cbd4542014f921548180ded1b826c90b6f36e86ca54ad94c7cbfb18edcfe2c214772c775d978108d2666f5a3
7
- data.tar.gz: 6a9fcf6b0c2f499cc282b7792ba8c962c313de903ef535283dea40f5c81454cb49b1999361a2f5bab41671267eee6eb9641f0e8972d3cdefd6091971e4e03541
6
+ metadata.gz: 418d81444b7cbb94057b2fbe0c605c88c1dc7746e1c61746142e34de10997fd250aebde65300b8119cd835fb4966e4507c073cfd723fca10c0299f57b711c4ce
7
+ data.tar.gz: 3dc7fc75adab48f5a0f6cd84bf12e852faa2818f4020fe33372e78b4af053ea224a0d6cd6abfa9762f569582ee756d64c0918029d69e54db068d0b171ff7695b
@@ -1,4 +1,4 @@
1
1
  <% form.fields_for :settings, form.object.settings do |settings_fields| %>
2
- <%= settings_fields.select :max_results, [4, 8, 12], prompt: "", label: max_results_label %>
2
+ <%= settings_fields.number_field :max_results, label: max_results_label %>
3
3
  <%= settings_fields.select :order, order_select, prompt: "", label: order_label %>
4
4
  <% end %>
@@ -46,16 +46,28 @@ module Decidim
46
46
  end
47
47
  end
48
48
 
49
+ protected
50
+
51
+ def event_arguments
52
+ {
53
+ resource: initiative,
54
+ extra: {
55
+ event_author: form.current_user,
56
+ locale:
57
+ }
58
+ }
59
+ end
60
+
49
61
  private
50
62
 
51
- attr_reader :form, :attachment
63
+ attr_reader :form, :attachment, :initiative
52
64
 
53
65
  # Creates the initiative and all default components
54
66
  def create_initiative
55
- initiative = build_initiative
67
+ build_initiative
56
68
  return initiative unless initiative.valid?
57
69
 
58
- initiative.transaction do
70
+ with_events(with_transaction: true) do
59
71
  initiative.save!
60
72
 
61
73
  @attached_to = initiative
@@ -72,7 +84,7 @@ module Decidim
72
84
  end
73
85
 
74
86
  def build_initiative
75
- Initiative.new(
87
+ @initiative = Initiative.new(
76
88
  organization: form.current_organization,
77
89
  title: { current_locale => form.title },
78
90
  description: { current_locale => form.description },
@@ -39,22 +39,36 @@ module Decidim
39
39
  return broadcast(:invalid) if gallery_invalid?
40
40
  end
41
41
 
42
- @initiative = Decidim.traceability.update!(
43
- initiative,
44
- current_user,
45
- attributes
46
- )
42
+ with_events(with_transaction: true) do
43
+ @initiative = Decidim.traceability.update!(
44
+ initiative,
45
+ current_user,
46
+ attributes
47
+ )
47
48
 
48
- photo_cleanup!
49
- document_cleanup!
50
- create_attachments if process_attachments?
51
- create_gallery if process_gallery?
49
+ photo_cleanup!
50
+ document_cleanup!
51
+ create_attachments if process_attachments?
52
+ create_gallery if process_gallery?
53
+ end
52
54
 
53
55
  broadcast(:ok, initiative)
54
56
  rescue ActiveRecord::RecordInvalid
55
57
  broadcast(:invalid, initiative)
56
58
  end
57
59
 
60
+ protected
61
+
62
+ def event_arguments
63
+ {
64
+ resource: initiative,
65
+ extra: {
66
+ event_author: form.current_user,
67
+ locale:
68
+ }
69
+ }
70
+ end
71
+
58
72
  private
59
73
 
60
74
  attr_reader :form, :initiative
@@ -51,7 +51,7 @@ module Decidim
51
51
  def detect_initiative
52
52
  request.env["current_initiative"] ||
53
53
  Initiative.find_by(
54
- id: (id_from_slug(params[:slug]) || id_from_slug(params[:initiative_slug]) || params[:initiative_id] || params[:id]),
54
+ id: id_from_slug(params[:slug]) || id_from_slug(params[:initiative_slug]) || params[:initiative_id] || params[:id],
55
55
  organization: current_organization
56
56
  )
57
57
  end
@@ -5,6 +5,8 @@ module Decidim
5
5
  module Admin
6
6
  # The main admin application controller for initiatives
7
7
  class ApplicationController < Decidim::Admin::ApplicationController
8
+ helper Decidim::Initiatives::ScopesHelper
9
+
8
10
  layout "decidim/admin/initiatives"
9
11
 
10
12
  register_permissions(::Decidim::Initiatives::Admin::ApplicationController,
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Initiatives
5
+ module Admin
6
+ # This controller allows sharing unpublished things.
7
+ # It is targeted for customizations for sharing unpublished things that lives under
8
+ # an initiative.
9
+ class ComponentShareTokensController < Decidim::Admin::ShareTokensController
10
+ include InitiativeAdmin
11
+
12
+ def resource
13
+ @resource ||= current_participatory_space.components.find(params[:component_id])
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Initiatives
5
+ module Admin
6
+ # This controller allows sharing unpublished things.
7
+ # It is targeted for customizations for sharing unpublished things that lives under
8
+ # an initiative.
9
+ class InitiativeShareTokensController < Decidim::Admin::ShareTokensController
10
+ include InitiativeAdmin
11
+
12
+ def resource
13
+ current_initiative
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -172,19 +172,19 @@ module Decidim
172
172
 
173
173
  @votes = current_initiative.votes
174
174
 
175
- output = render_to_string(
176
- pdf: "votes_#{current_initiative.id}",
177
- layout: "decidim/admin/initiatives_votes",
178
- template: "decidim/initiatives/admin/initiatives/export_pdf_signatures",
179
- format: [:pdf]
180
- )
181
- output = pdf_signature_service.new(pdf: output).signed_pdf if pdf_signature_service
175
+ serializer = Decidim::Forms::UserAnswersSerializer
176
+ pdf_export = Decidim::Exporters::InitiativeVotesPDF.new(@votes, current_initiative, serializer).export
177
+
178
+ output = if pdf_signature_service
179
+ pdf_signature_service.new(pdf: pdf_export.read).signed_pdf
180
+ else
181
+ pdf_export.read
182
+ end
182
183
 
183
184
  respond_to do |format|
184
185
  format.pdf do
185
186
  send_data(output, filename: "votes_#{current_initiative.id}.pdf", type: "application/pdf")
186
187
  end
187
- format.html
188
188
  end
189
189
  end
190
190
 
@@ -14,6 +14,7 @@ module Decidim
14
14
  helper Decidim::Admin::IconLinkHelper
15
15
  helper InitiativeHelper
16
16
  helper SignatureTypeOptionsHelper
17
+ helper Decidim::ActionAuthorizationHelper
17
18
 
18
19
  helper_method :scopes
19
20
  helper_method :areas
@@ -63,7 +64,7 @@ module Decidim
63
64
 
64
65
  path = promotal_committee_required? ? "promotal_committee" : "finish"
65
66
 
66
- redirect_to send("#{path}_create_initiative_index_path".to_sym)
67
+ redirect_to send(:"#{path}_create_initiative_index_path")
67
68
  end
68
69
 
69
70
  on(:invalid) do
@@ -110,7 +111,7 @@ module Decidim
110
111
  return if action_name == destination_step
111
112
  return if initiative_type_id.present? && initiative_type.present?
112
113
 
113
- redirect_to send("#{destination_step}_create_initiative_index_path".to_sym)
114
+ redirect_to send(:"#{destination_step}_create_initiative_index_path")
114
115
  end
115
116
 
116
117
  def scopes
@@ -3,7 +3,7 @@
3
3
  # i18n-tasks-use t('decidim.initiatives.show.badge_name.accepted')
4
4
  # i18n-tasks-use t('decidim.initiatives.show.badge_name.created')
5
5
  # i18n-tasks-use t('decidim.initiatives.show.badge_name.discarded')
6
- # i18n-tasks-use t('decidim.initiatives.show.badge_name.published')
6
+ # i18n-tasks-use t('decidim.initiatives.show.badge_name.open')
7
7
  # i18n-tasks-use t('decidim.initiatives.show.badge_name.rejected')
8
8
  # i18n-tasks-use t('decidim.initiatives.show.badge_name.validating')
9
9
  #
@@ -17,6 +17,7 @@ module Decidim
17
17
  helper PaginateHelper
18
18
  helper InitiativeHelper
19
19
  helper SignatureTypeOptionsHelper
20
+ helper Decidim::ActionAuthorizationHelper
20
21
 
21
22
  include InitiativeSlug
22
23
  include FilterResource
@@ -108,6 +109,8 @@ module Decidim
108
109
 
109
110
  def print
110
111
  enforce_permission_to :print, :initiative, initiative: current_initiative
112
+ output = Decidim::Initiatives::ApplicationFormPDF.new(current_initiative).render
113
+ send_data(output, filename: "initiative_submit_#{current_initiative.id}.pdf", type: "application/pdf")
111
114
  end
112
115
 
113
116
  private
@@ -21,7 +21,7 @@ module Decidim
21
21
  }
22
22
 
23
23
  def signature_dates_required?
24
- @signature_dates_required ||= context.initiative.state == "published"
24
+ @signature_dates_required ||= context.initiative.state == "open"
25
25
  end
26
26
  end
27
27
  end
@@ -48,7 +48,7 @@ module Decidim
48
48
  [
49
49
  initiative.id,
50
50
  document_number || signer.id,
51
- Rails.application.secrets.secret_key_base
51
+ Rails.application.secret_key_base
52
52
  ].compact.join("-")
53
53
  )
54
54
  end
@@ -9,7 +9,7 @@ module Decidim
9
9
 
10
10
  def metadata_badge_css_class(initiative)
11
11
  case initiative
12
- when "accepted", "published"
12
+ when "accepted", "open"
13
13
  "success"
14
14
  when "rejected", "discarded"
15
15
  "alert"
@@ -30,44 +30,6 @@ module Decidim
30
30
  I18n.t(state, scope: "decidim.initiatives.admin_states", default: :created)
31
31
  end
32
32
 
33
- def authorized_create_modal_button(type, html_options, &)
34
- tag = "button"
35
- html_options ||= {}
36
-
37
- if current_user
38
- if action_authorized_to("create", permissions_holder: type).ok?
39
- html_options["data-dialog-open"] = "not-authorized-modal"
40
- else
41
- html_options["data-dialog-open"] = "authorizationModal"
42
- html_options["data-dialog-remote-url"] = authorization_create_modal_initiative_path(type)
43
- end
44
- else
45
- html_options["data-dialog-open"] = "loginModal"
46
- end
47
-
48
- html_options["onclick"] = "event.preventDefault();"
49
-
50
- send("#{tag}_to", "/", html_options, &)
51
- end
52
-
53
- def authorized_vote_modal_button(initiative, html_options, &)
54
- return if current_user && action_authorized_to("vote", resource: initiative, permissions_holder: initiative.type).ok?
55
-
56
- tag = "button"
57
- html_options ||= {}
58
-
59
- if current_user
60
- html_options["data-dialog-open"] = "authorizationModal"
61
- html_options["data-dialog-remote-url"] = authorization_sign_modal_initiative_path(initiative)
62
- else
63
- html_options["data-dialog-open"] = "loginModal"
64
- end
65
-
66
- html_options["onclick"] = "event.preventDefault();"
67
-
68
- send("#{tag}_to", "/", html_options, &)
69
- end
70
-
71
33
  def can_edit_custom_signature_end_date?(initiative)
72
34
  return false unless initiative.custom_signature_end_date_enabled?
73
35
 
@@ -26,12 +26,15 @@ module Decidim
26
26
  # i18n-tasks-use t('decidim.initiatives.initiatives.filters.author')
27
27
  def filter_sections
28
28
  sections = [
29
- { method: :with_any_state, collection: filter_states_values, label_scope: "decidim.initiatives.initiatives.filters", id: "state" },
30
- { method: :with_any_scope, collection: filter_global_scopes_values, label_scope: "decidim.initiatives.initiatives.filters", id: "scope" }
29
+ { method: :with_any_state, collection: filter_states_values, label: t("decidim.initiatives.initiatives.filters.state"), id: "state" },
30
+ { method: :with_any_scope, collection: filter_global_scopes_values, label: t("decidim.initiatives.initiatives.filters.scope"), id: "scope" }
31
31
  ]
32
- sections.append(method: :with_any_type, collection: filter_types_values, label_scope: "decidim.initiatives.initiatives.filters", id: "type") unless single_initiative_type?
33
- sections.append(method: :with_any_area, collection: filter_areas_values, label_scope: "decidim.initiatives.initiatives.filters", id: "area")
34
- sections.append(method: :author, collection: filter_author_values, label_scope: "decidim.initiatives.initiatives.filters", id: "author") if current_user
32
+ unless single_initiative_type?
33
+ sections.append(method: :with_any_type, collection: filter_types_values, label: t("decidim.initiatives.initiatives.filters.type"),
34
+ id: "type")
35
+ end
36
+ sections.append(method: :with_any_area, collection: filter_areas_values, label: t("decidim.initiatives.initiatives.filters.area"), id: "area")
37
+ sections.append(method: :author, collection: filter_author_values, label: t("decidim.initiatives.initiatives.filters.author"), id: "author") if current_user
35
38
  sections.reject { |item| item[:collection].blank? }
36
39
  end
37
40
 
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Initiatives
5
+ # A Helper to render scopes, including a global scope, for forms.
6
+ module ScopesHelper
7
+ include DecidimFormHelper
8
+ include TranslatableAttributes
9
+
10
+ # Renders a scopes select field in a form.
11
+ # form - FormBuilder object
12
+ # name - attribute name
13
+ # options - An optional Hash with options:
14
+ #
15
+ # Returns nothing.
16
+ def scopes_select_field(form, name, root: false, options: {}, html_options: {})
17
+ options = options.merge(include_blank: I18n.t("decidim.scopes.prompt")) unless options.has_key?(:include_blank)
18
+
19
+ form.select(
20
+ name,
21
+ ordered_scopes_descendants_for_select(root),
22
+ options,
23
+ html_options
24
+ )
25
+ end
26
+
27
+ def ordered_scopes_descendants(root = nil)
28
+ root = try(:current_participatory_space)&.scope if root == false
29
+ if root.present?
30
+ root.descendants
31
+ else
32
+ current_organization.scopes
33
+ end.sort { |a, b| a.part_of.reverse <=> b.part_of.reverse }
34
+ end
35
+
36
+ def ordered_scopes_descendants_for_select(root = nil)
37
+ ordered_scopes_descendants(root).map do |scope|
38
+ [" #{"&nbsp;" * 4 * (scope.part_of.count - 1)} #{translated_attribute(scope.name)}".html_safe, scope&.id]
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -3,6 +3,8 @@
3
3
  module Decidim
4
4
  module Initiatives
5
5
  class ExportInitiativesJob < ApplicationJob
6
+ include Decidim::PrivateDownloadHelper
7
+
6
8
  queue_as :exports
7
9
 
8
10
  def perform(user, organization, format, collection_ids = nil)
@@ -11,7 +13,9 @@ module Decidim
11
13
  serializer
12
14
  ).export
13
15
 
14
- ExportMailer.export(user, "initiatives", export_data).deliver_now
16
+ private_export = attach_archive(export_data, "initiatives", user)
17
+
18
+ ExportMailer.export(user, private_export).deliver_later
15
19
  end
16
20
 
17
21
  private
@@ -14,6 +14,7 @@ module Decidim
14
14
  include Decidim::HasAttachmentCollections
15
15
  include Decidim::Traceable
16
16
  include Decidim::Loggable
17
+ include Decidim::DownloadYourData
17
18
  include Decidim::Initiatives::InitiativeSlug
18
19
  include Decidim::Resourceable
19
20
  include Decidim::HasReference
@@ -24,6 +25,8 @@ module Decidim
24
25
  include Decidim::HasResourcePermission
25
26
  include Decidim::HasArea
26
27
  include Decidim::FilterableResource
28
+ include Decidim::Reportable
29
+ include Decidim::ShareableWithToken
27
30
 
28
31
  translatable_fields :title, :description, :answer
29
32
 
@@ -63,7 +66,7 @@ module Decidim
63
66
  as: :participatory_space
64
67
 
65
68
  enum signature_type: [:online, :offline, :any], _suffix: true
66
- enum state: [:created, :validating, :discarded, :published, :rejected, :accepted]
69
+ enum state: [:created, :validating, :discarded, :open, :rejected, :accepted]
67
70
 
68
71
  validates :title, :description, :state, :signature_type, presence: true
69
72
  validates :hashtag,
@@ -72,8 +75,8 @@ module Decidim
72
75
  validate :signature_type_allowed
73
76
 
74
77
  scope :open, lambda {
75
- where.not(state: [:discarded, :rejected, :accepted, :created])
76
- .currently_signable
78
+ where(state: [:open])
79
+ .currently_signable
77
80
  }
78
81
  scope :closed, lambda {
79
82
  where(state: [:discarded, :rejected, :accepted])
@@ -85,12 +88,12 @@ module Decidim
85
88
  scope_search_multi :with_any_state, [:accepted, :rejected, :answered, :open, :closed]
86
89
 
87
90
  scope :currently_signable, lambda {
88
- where("signature_start_date <= ?", Date.current)
89
- .where("signature_end_date >= ?", Date.current)
91
+ where(signature_start_date: ..Date.current)
92
+ .where(signature_end_date: Date.current..)
90
93
  }
91
94
  scope :currently_unsignable, lambda {
92
95
  where("signature_start_date > ?", Date.current)
93
- .or(where("signature_end_date < ?", Date.current))
96
+ .or(where(signature_end_date: ...Date.current))
94
97
  }
95
98
 
96
99
  scope :answered, -> { where.not(answered_at: nil) }
@@ -155,10 +158,26 @@ module Decidim
155
158
  # is Resourceable instead of ParticipatorySpaceResourceable so we cannot use `visible?`
156
159
  index_on_update: ->(initiative) { initiative.published? })
157
160
 
161
+ def self.export_serializer
162
+ Decidim::Initiatives::DownloadYourDataInitiativeSerializer
163
+ end
164
+
158
165
  def self.log_presenter_class_for(_log)
159
166
  Decidim::Initiatives::AdminLog::InitiativePresenter
160
167
  end
161
168
 
169
+ def self.ransackable_attributes(auth_object = nil)
170
+ base = %w(search_text title description id id_string supports_count author_name author_nickname)
171
+
172
+ return base unless auth_object&.admin?
173
+
174
+ base + %w(published_at state decidim_area_id type_id)
175
+ end
176
+
177
+ def self.ransackable_associations(_auth_object = nil)
178
+ %w(area scope taxonomies)
179
+ end
180
+
162
181
  def self.ransackable_scopes(_auth_object = nil)
163
182
  [:with_any_state, :with_any_type, :with_any_scope, :with_any_area]
164
183
  end
@@ -184,26 +203,6 @@ module Decidim
184
203
  decidim_user_group_id.nil?
185
204
  end
186
205
 
187
- # Public: check if an initiative is open
188
- #
189
- # Returns a Boolean
190
- def open?
191
- !closed?
192
- end
193
-
194
- # Public: Checks if an initiative is closed. An initiative is closed when
195
- # at least one of the following conditions is true:
196
- #
197
- # * It has been discarded.
198
- # * It has been rejected.
199
- # * It has been accepted.
200
- # * Signature collection period has finished.
201
- #
202
- # Returns a Boolean
203
- def closed?
204
- discarded? || rejected? || accepted? || !votes_enabled?
205
- end
206
-
207
206
  # Public: Returns the author name. If it has been created by an organization it will
208
207
  # return the organization's name. Otherwise it will return author's name.
209
208
  #
@@ -212,6 +211,16 @@ module Decidim
212
211
  user_group&.name || author.name
213
212
  end
214
213
 
214
+ # Public: Overrides the `reported_content_url` Reportable concern method.
215
+ def reported_content_url
216
+ ResourceLocatorPresenter.new(self).url
217
+ end
218
+
219
+ # Public: Overrides the `reported_attributes` Reportable concern method.
220
+ def reported_attributes
221
+ [:title, :description]
222
+ end
223
+
215
224
  def votes_enabled?
216
225
  published? &&
217
226
  signature_start_date <= Date.current &&
@@ -254,7 +263,7 @@ module Decidim
254
263
 
255
264
  update(
256
265
  published_at: Time.current,
257
- state: "published",
266
+ state: "open",
258
267
  signature_start_date: Date.current,
259
268
  signature_end_date: signature_end_date || (Date.current + Decidim::Initiatives.default_signature_time_period_length)
260
269
  )
@@ -465,6 +474,10 @@ module Decidim
465
474
  ActionAuthorizer.new(user, "comment", self, nil).authorize.ok?
466
475
  end
467
476
 
477
+ def shareable_url(share_token)
478
+ EngineRouter.main_proxy(self).initiative_url(self, share_token: share_token.token)
479
+ end
480
+
468
481
  def self.ransack(params = {}, options = {})
469
482
  Initiatives::InitiativeSearch.new(self, params, options)
470
483
  end
@@ -7,6 +7,11 @@ module Decidim
7
7
  class_name: "Decidim::InitiativesType",
8
8
  inverse_of: :scopes
9
9
 
10
+ belongs_to :taxonomy,
11
+ foreign_key: "decidim_taxonomy_id",
12
+ class_name: "Decidim::Taxonomy",
13
+ optional: true
14
+
10
15
  belongs_to :scope,
11
16
  foreign_key: "decidim_scopes_id",
12
17
  class_name: "Decidim::Scope",
@@ -34,5 +39,9 @@ module Decidim
34
39
 
35
40
  scope&.name.presence || { I18n.locale.to_s => I18n.t("decidim.initiatives.unavailable_scope") }
36
41
  end
42
+
43
+ def taxonomy_name
44
+ taxonomy&.name.presence || { I18n.locale.to_s => I18n.t("decidim.initiatives.unavailable_scope") }
45
+ end
37
46
  end
38
47
  end
@@ -39,6 +39,7 @@ module Decidim
39
39
  initiative_export_action?
40
40
  initiatives_settings_action?
41
41
  moderator_action?
42
+ share_tokens_action?
42
43
  allow! if permission_action.subject == :attachment
43
44
 
44
45
  permission_action
@@ -179,6 +180,12 @@ module Decidim
179
180
  allow!
180
181
  end
181
182
 
183
+ def share_tokens_action?
184
+ return unless permission_action.subject == :share_tokens
185
+
186
+ allow!
187
+ end
188
+
182
189
  def read_initiative_list_action?
183
190
  return unless permission_action.subject == :initiative &&
184
191
  permission_action.action == :list
@@ -54,7 +54,8 @@ module Decidim
54
54
  return unless [:initiative, :participatory_space].include?(permission_action.subject) &&
55
55
  permission_action.action == :read
56
56
 
57
- return allow! if initiative.published? || initiative.rejected? || initiative.accepted?
57
+ return allow! if initiative.open? || initiative.rejected? || initiative.accepted?
58
+ return allow! if user_can_preview_space?
58
59
  return allow! if user && authorship_or_admin?
59
60
 
60
61
  disallow!
@@ -110,11 +111,11 @@ module Decidim
110
111
  end
111
112
 
112
113
  def access_request_without_user?
113
- (!initiative.published? && initiative.promoting_committee_enabled?) || Decidim::Initiatives.do_not_require_authorization
114
+ (!initiative.open? && initiative.promoting_committee_enabled?) || Decidim::Initiatives.do_not_require_authorization
114
115
  end
115
116
 
116
117
  def access_request_membership?
117
- !initiative.published? &&
118
+ !initiative.open? &&
118
119
  initiative.promoting_committee_enabled? &&
119
120
  !initiative.has_authorship?(user) &&
120
121
  (
@@ -195,6 +196,12 @@ module Decidim
195
196
  )
196
197
  end
197
198
 
199
+ def user_can_preview_space?
200
+ context[:share_token].present? && Decidim::ShareToken.use!(token_for: initiative, token: context[:share_token], user:)
201
+ rescue ActiveRecord::RecordNotFound, StandardError
202
+ nil
203
+ end
204
+
198
205
  def initiative_committee_action?
199
206
  return unless permission_action.subject == :initiative_committee_member
200
207
 
@@ -23,7 +23,7 @@ module Decidim
23
23
  def query
24
24
  Decidim::Initiative
25
25
  .where(state: "validating")
26
- .where("updated_at < ?", @period_length)
26
+ .where(updated_at: ...@period_length)
27
27
  end
28
28
  end
29
29
  end
@@ -10,9 +10,9 @@ module Decidim
10
10
  def query
11
11
  Decidim::Initiative
12
12
  .includes(:scoped_type)
13
- .where(state: "published")
13
+ .where(state: "open")
14
14
  .where(signature_type: "online")
15
- .where("signature_end_date < ?", Date.current)
15
+ .where(signature_end_date: ...Date.current)
16
16
  end
17
17
  end
18
18
  end