decidim-initiatives 0.30.1 → 0.31.0.rc1

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 (147) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +46 -9
  3. data/app/cells/decidim/initiatives/content_blocks/highlighted_initiatives_settings_form/show.erb +7 -2
  4. data/app/cells/decidim/initiatives/initiative_g_cell.rb +5 -1
  5. data/app/commands/decidim/initiatives/admin/publish_initiative.rb +1 -5
  6. data/app/commands/decidim/initiatives/admin/update_initiative.rb +1 -2
  7. data/app/commands/decidim/initiatives/create_initiative.rb +0 -1
  8. data/app/commands/decidim/initiatives/update_initiative.rb +1 -3
  9. data/app/commands/decidim/initiatives/vote_initiative.rb +1 -11
  10. data/app/controllers/concerns/decidim/initiatives/has_signature_workflow.rb +36 -0
  11. data/app/controllers/concerns/decidim/initiatives/needs_initiative.rb +1 -12
  12. data/app/controllers/decidim/initiatives/admin/initiatives_controller.rb +2 -2
  13. data/app/controllers/decidim/initiatives/admin/initiatives_settings_controller.rb +1 -1
  14. data/app/controllers/decidim/initiatives/admin/initiatives_type_scopes_controller.rb +2 -2
  15. data/app/controllers/decidim/initiatives/admin/initiatives_types_controller.rb +2 -2
  16. data/app/controllers/decidim/initiatives/committee_requests_controller.rb +10 -2
  17. data/app/controllers/decidim/initiatives/create_initiative_controller.rb +84 -18
  18. data/app/controllers/decidim/initiatives/initiative_signatures_controller.rb +133 -42
  19. data/app/controllers/decidim/initiatives/initiative_votes_controller.rb +3 -2
  20. data/app/controllers/decidim/initiatives/initiatives_controller.rb +21 -2
  21. data/app/forms/decidim/initiatives/admin/initiative_form.rb +0 -1
  22. data/app/forms/decidim/initiatives/initiative_form.rb +0 -3
  23. data/app/helpers/decidim/initiatives/application_helper.rb +2 -0
  24. data/app/helpers/decidim/initiatives/initiatives_helper.rb +0 -1
  25. data/app/models/decidim/initiative.rb +7 -31
  26. data/app/models/decidim/initiatives_committee_member.rb +1 -1
  27. data/app/models/decidim/initiatives_type.rb +5 -2
  28. data/app/models/decidim/initiatives_vote.rb +2 -2
  29. data/app/packs/entrypoints/decidim_initiatives.js +1 -1
  30. data/app/packs/entrypoints/decidim_initiatives_admin.scss +1 -1
  31. data/app/packs/src/decidim/initiatives/admin/initiatives_types.js +2 -11
  32. data/app/packs/src/decidim/initiatives/admin/invite_users.js +1 -1
  33. data/app/packs/src/decidim/initiatives/application.js +1 -1
  34. data/app/packs/src/decidim/initiatives/check_code.js +114 -0
  35. data/app/packs/src/decidim/initiatives/initiative_creation_wizard.js +16 -0
  36. data/app/packs/src/decidim/initiatives/scoped_type.js +1 -1
  37. data/app/packs/stylesheets/initiatives.scss +16 -2
  38. data/app/permissions/decidim/initiatives/admin/permissions.rb +4 -7
  39. data/app/permissions/decidim/initiatives/permissions.rb +26 -16
  40. data/app/presenters/decidim/initiative_presenter.rb +12 -6
  41. data/app/presenters/decidim/initiatives/admin_log/initiative_presenter.rb +1 -2
  42. data/app/queries/decidim/initiatives/initiatives_stats_followers_count.rb +14 -0
  43. data/app/queries/decidim/initiatives/initiatives_stats_participants_count.rb +14 -0
  44. data/app/serializers/decidim/initiatives/open_data_initiative_serializer.rb +0 -1
  45. data/app/services/decidim/initiatives/data_encryptor.rb +1 -1
  46. data/app/services/decidim/initiatives/legacy_signature_handler.rb +25 -0
  47. data/app/services/decidim/initiatives/progress_notifier.rb +1 -7
  48. data/app/services/decidim/initiatives/signature_handler.rb +248 -0
  49. data/app/services/decidim/initiatives/status_change_notifier.rb +1 -7
  50. data/app/views/decidim/initiatives/admin/committee_requests/index.html.erb +29 -11
  51. data/app/views/decidim/initiatives/admin/exports/_dropdown.html.erb +17 -20
  52. data/app/views/decidim/initiatives/admin/initiatives/_form.html.erb +7 -13
  53. data/app/views/decidim/initiatives/admin/initiatives/_initiative_attachments.erb +2 -2
  54. data/app/views/decidim/initiatives/admin/initiatives/index.html.erb +76 -47
  55. data/app/views/decidim/initiatives/admin/initiatives_types/_form.html.erb +13 -21
  56. data/app/views/decidim/initiatives/admin/initiatives_types/_initiative_type_scopes.html.erb +28 -12
  57. data/app/views/decidim/initiatives/admin/initiatives_types/index.html.erb +33 -15
  58. data/app/views/decidim/initiatives/create_initiative/_committee_member.html.erb +27 -0
  59. data/app/views/decidim/initiatives/create_initiative/_return_to_initiatives_button.html.erb +3 -0
  60. data/app/views/decidim/initiatives/create_initiative/_send_to_technical_validation_button.html.erb +10 -0
  61. data/app/views/decidim/initiatives/create_initiative/_share_committee_link.html.erb +5 -1
  62. data/app/views/decidim/initiatives/create_initiative/fill_data.html.erb +7 -11
  63. data/app/views/decidim/initiatives/create_initiative/finish.html.erb +16 -13
  64. data/app/views/decidim/initiatives/create_initiative/promotal_committee.html.erb +33 -6
  65. data/app/views/decidim/initiatives/create_initiative/select_initiative_type.html.erb +40 -26
  66. data/app/views/decidim/initiatives/initiative_signatures/_sms_code_form.html.erb +22 -0
  67. data/app/views/decidim/initiatives/initiative_signatures/_sms_phone_number_form.html.erb +13 -0
  68. data/app/views/decidim/initiatives/initiative_signatures/fill_personal_data.html.erb +23 -22
  69. data/app/views/decidim/initiatives/initiative_signatures/finish.html.erb +17 -5
  70. data/app/views/decidim/initiatives/initiative_signatures/sms_code.html.erb +6 -8
  71. data/app/views/decidim/initiatives/initiative_signatures/sms_phone_number.html.erb +3 -8
  72. data/app/views/decidim/initiatives/initiative_signatures/update_buttons_and_counters.js.erb +3 -14
  73. data/app/views/decidim/initiatives/initiative_votes/update_buttons_and_counters.js.erb +3 -14
  74. data/app/views/decidim/initiatives/initiatives/_committee_members.html.erb +1 -1
  75. data/app/views/decidim/initiatives/initiatives/_form.html.erb +1 -3
  76. data/app/views/decidim/initiatives/initiatives/_new_initiative_button.html.erb +10 -3
  77. data/app/views/decidim/initiatives/initiatives/_pending_initiatives.html.erb +5 -0
  78. data/app/views/decidim/initiatives/initiatives/index.html.erb +8 -0
  79. data/app/views/decidim/initiatives/initiatives/show.html.erb +2 -2
  80. data/app/views/layouts/decidim/_initiative_signature_creation_header.html.erb +20 -2
  81. data/app/views/layouts/decidim/admin/_manage_initiatives.html.erb +1 -1
  82. data/app/views/layouts/decidim/initiative_signature_creation.html.erb +3 -1
  83. data/config/assets.rb +2 -2
  84. data/config/locales/ar.yml +0 -45
  85. data/config/locales/bg.yml +0 -54
  86. data/config/locales/ca-IT.yml +99 -51
  87. data/config/locales/ca.yml +99 -51
  88. data/config/locales/cs.yml +93 -54
  89. data/config/locales/de.yml +100 -52
  90. data/config/locales/el.yml +0 -45
  91. data/config/locales/en.yml +99 -51
  92. data/config/locales/es-MX.yml +99 -51
  93. data/config/locales/es-PY.yml +99 -51
  94. data/config/locales/es.yml +99 -51
  95. data/config/locales/eu.yml +120 -72
  96. data/config/locales/fi-plain.yml +99 -51
  97. data/config/locales/fi.yml +99 -51
  98. data/config/locales/fr-CA.yml +44 -51
  99. data/config/locales/fr.yml +44 -51
  100. data/config/locales/ga-IE.yml +0 -17
  101. data/config/locales/gl.yml +0 -41
  102. data/config/locales/hu.yml +0 -54
  103. data/config/locales/id-ID.yml +0 -40
  104. data/config/locales/is-IS.yml +0 -22
  105. data/config/locales/it.yml +0 -53
  106. data/config/locales/ja.yml +98 -49
  107. data/config/locales/lb.yml +0 -50
  108. data/config/locales/lt.yml +0 -56
  109. data/config/locales/lv.yml +0 -46
  110. data/config/locales/nl.yml +0 -47
  111. data/config/locales/no.yml +0 -53
  112. data/config/locales/pl.yml +0 -56
  113. data/config/locales/pt-BR.yml +0 -53
  114. data/config/locales/pt.yml +0 -53
  115. data/config/locales/ro-RO.yml +92 -50
  116. data/config/locales/ru.yml +0 -25
  117. data/config/locales/sk.yml +0 -43
  118. data/config/locales/sl.yml +0 -1
  119. data/config/locales/sv.yml +10 -53
  120. data/config/locales/tr-TR.yml +0 -53
  121. data/config/locales/uk.yml +0 -25
  122. data/config/locales/zh-CN.yml +0 -45
  123. data/config/locales/zh-TW.yml +0 -53
  124. data/db/migrate/20250605104500_remove_hashtag_column_initiatives.rb +7 -0
  125. data/lib/decidim/api/initiative_api_type.rb +3 -0
  126. data/lib/decidim/api/initiative_type.rb +23 -4
  127. data/lib/decidim/exporters/initiative_votes_pdf.rb +1 -1
  128. data/lib/decidim/initiatives/default_signature_authorizer.rb +17 -0
  129. data/lib/decidim/initiatives/engine.rb +17 -14
  130. data/lib/decidim/initiatives/menu.rb +1 -1
  131. data/lib/decidim/initiatives/participatory_space.rb +15 -1
  132. data/lib/decidim/initiatives/seeds.rb +1 -2
  133. data/lib/decidim/initiatives/signature_workflow_manifest.rb +176 -0
  134. data/lib/decidim/initiatives/signatures.rb +12 -0
  135. data/lib/decidim/initiatives/test/factories.rb +7 -7
  136. data/lib/decidim/initiatives/test/initiatives_signatures_test_helpers.rb +19 -0
  137. data/lib/decidim/initiatives/validatable_authorizations.rb +83 -0
  138. data/lib/decidim/initiatives/version.rb +1 -1
  139. data/lib/decidim/initiatives.rb +23 -12
  140. metadata +33 -21
  141. data/app/events/decidim/initiatives/endorse_initiative_event.rb +0 -13
  142. data/app/forms/decidim/initiatives/vote_form.rb +0 -208
  143. data/app/packs/src/decidim/initiatives/identity_selector_dialog.js +0 -14
  144. data/app/services/decidim/initiatives/pdf_signature_example.rb +0 -110
  145. data/app/views/decidim/initiatives/initiative_signatures/_wizard_steps.html.erb +0 -15
  146. data/app/views/decidim/initiatives/initiatives/_interactions.html.erb +0 -10
  147. data/app/views/layouts/decidim/_initiative_header.html.erb +0 -27
@@ -0,0 +1,114 @@
1
+ const focusDigit = (digit) => {
2
+ const length = digit.value.length;
3
+ digit.focus();
4
+ setTimeout(() => digit.setSelectionRange(length, length), 0);
5
+ };
6
+
7
+ const validateCode = (path, code) => {
8
+ return fetch(path, {
9
+ method: "PUT",
10
+ cache: "no-cache",
11
+ headers: {
12
+ "Content-Type": "application/json",
13
+ "X-CSRF-Token": document.querySelector("meta[name=csrf-token]")?.content
14
+ },
15
+ body: JSON.stringify({ confirmation: { "verification_code": code } })
16
+ }).
17
+ then((response) => response.json()).
18
+ then((json) => { return json.sms_code === "OK" });
19
+ };
20
+
21
+ const updateSubmit = (enable, includeAnnouncement) => {
22
+ const correctAnnouncement = document.querySelector(".code-correct-announcement");
23
+ const incorrectAnnouncement = document.querySelector(".code-incorrect-announcement");
24
+ const submitButton = document.querySelector("[data-submit-verification-code]");
25
+ const resendCodeMessage = document.querySelector("[data-resend-code]");
26
+
27
+ if (enable) {
28
+ if (includeAnnouncement) {
29
+ correctAnnouncement.classList.remove("hidden");
30
+ resendCodeMessage.classList.add("hidden");
31
+ } else {
32
+ correctAnnouncement.classList.add("hidden");
33
+ resendCodeMessage.classList.remove("hidden");
34
+ }
35
+ incorrectAnnouncement.classList.add("hidden");
36
+ submitButton.classList.remove("hidden");
37
+ submitButton.disabled = false;
38
+ } else {
39
+ if (includeAnnouncement) {
40
+ incorrectAnnouncement.classList.remove("hidden");
41
+ resendCodeMessage.classList.add("hidden");
42
+ } else {
43
+ incorrectAnnouncement.classList.add("hidden");
44
+ resendCodeMessage.classList.remove("hidden");
45
+ }
46
+ correctAnnouncement.classList.add("hidden");
47
+ submitButton.classList.add("hidden");
48
+ submitButton.disabled = true;
49
+ }
50
+ }
51
+
52
+ const updateValue = (codeInput, event, digitsInputs) => {
53
+ const checkCodePath = codeInput.dataset.checkCodePath;
54
+ const index = Number(event.target.dataset.verificationCode);
55
+ const prevDigit = digitsInputs[index - 1];
56
+ const nextDigit = digitsInputs[index + 1];
57
+ let digits = codeInput.value.split("");
58
+ const newDigit = event.target.value || "-";
59
+ if (newDigit.length > 0) {
60
+ const position = event.target.dataset.verificationCode;
61
+ digits[position] = newDigit;
62
+ const newCode = digits.join("")
63
+ if (codeInput.value !== newCode) {
64
+ codeInput.value = newCode;
65
+ if ((/^\d{6}$/).test(newCode)) {
66
+ validateCode(checkCodePath, newCode).then((validCode) => updateSubmit(validCode, true));
67
+ } else {
68
+ updateSubmit(false, false);
69
+ }
70
+ }
71
+
72
+ if (prevDigit && newDigit === "-") {
73
+ focusDigit(prevDigit);
74
+ } else if (nextDigit && newDigit !== "-") {
75
+ focusDigit(nextDigit);
76
+ }
77
+ }
78
+ };
79
+
80
+ const updatePosition = (codeInput, event, digitsInputs) => {
81
+ const index = Number(event.target.dataset.verificationCode);
82
+ const nextDigit = (() => {
83
+ if (event.key === "ArrowLeft" || ["Delete", "Backspace"].includes(event.key) && event.target.value === "") {
84
+ return digitsInputs[index - 1];
85
+ } else if (event.key === "ArrowRight" || (/^\d$/).test(event.key) && event.target.value.length > 0) {
86
+ return digitsInputs[index + 1];
87
+ }
88
+ return false;
89
+ })();
90
+
91
+ if (nextDigit) {
92
+ focusDigit(nextDigit);
93
+ }
94
+ return true;
95
+ };
96
+
97
+
98
+ const initializeCodeVerificator = (codeElement) => {
99
+ const codeInput = codeElement.querySelector("[data-check-code-path]");
100
+ const digitsInputs = codeElement.querySelectorAll("[data-verification-code]");
101
+
102
+ digitsInputs.forEach((digitInput) => {
103
+ digitInput.addEventListener("input", (event) => updateValue(codeInput, event, digitsInputs));
104
+ digitInput.addEventListener("keydown", (event) => updatePosition(codeInput, event, digitsInputs));
105
+ });
106
+ codeInput.value = "------";
107
+ };
108
+
109
+ document.addEventListener("turbo:load", () => {
110
+ const codeElement = document.querySelector("[data-check-code]");
111
+ if (codeElement) {
112
+ initializeCodeVerificator(codeElement);
113
+ }
114
+ });
@@ -0,0 +1,16 @@
1
+ document.addEventListener("turbo:load", () => {
2
+ const selectInitiativeType = document.getElementById("select-initiative-type");
3
+
4
+ if (selectInitiativeType) {
5
+ const submitButton = selectInitiativeType.querySelector('button[type="submit"]');
6
+ const radioButtons = selectInitiativeType.querySelectorAll('input[type="radio"][name="initiative[type_id]"]');
7
+
8
+ submitButton.disabled = true;
9
+
10
+ for (const radioButton of radioButtons) {
11
+ radioButton.addEventListener("click", () => {
12
+ submitButton.disabled = false;
13
+ });
14
+ }
15
+ }
16
+ });
@@ -27,7 +27,7 @@ const controlSelector = function (source, prefix, currentValueKey) {
27
27
  }
28
28
  };
29
29
 
30
- $(() => {
30
+ document.addEventListener("turbo:load", () => {
31
31
  let typeSelector = $("[data-scope-selector]");
32
32
  controlSelector(typeSelector, "scope", "scope-id");
33
33
  controlSelector(typeSelector, "signature-types", "signature-type");
@@ -3,7 +3,7 @@
3
3
 
4
4
  &__selection {
5
5
  .form-defaults {
6
- @apply my-10;
6
+ @apply my-8;
7
7
  }
8
8
 
9
9
  .card__highlight {
@@ -90,7 +90,7 @@
90
90
  }
91
91
 
92
92
  &__form__committee {
93
- @apply flex items-center px-4 py-2 border border-gray outline outline-1 outline-transparent rounded bg-background-2 focus:outline-2 focus:outline-secondary w-full;
93
+ @apply flex items-center px-4 py-2 border border-gray outline outline-1 outline-transparent rounded bg-background-2 focus:outline-2 focus:outline-secondary w-full mt-4;
94
94
 
95
95
  span {
96
96
  @apply text-black font-normal;
@@ -169,3 +169,17 @@
169
169
  .edit_initiative .profile__group__list {
170
170
  @apply w-full;
171
171
  }
172
+
173
+ .pending-initiatives {
174
+ @apply bg-background rounded-lg px-4 py-8 mb-12;
175
+
176
+ .card__grid {
177
+ @apply bg-white;
178
+
179
+ --tw-ring-color: #ddd;
180
+
181
+ &:hover {
182
+ --tw-ring-color: var(--tertiary);
183
+ }
184
+ }
185
+ }
@@ -39,7 +39,7 @@ module Decidim
39
39
  initiative_export_action?
40
40
  initiatives_settings_action?
41
41
  moderator_action?
42
- share_tokens_action?
42
+ share_token_action?
43
43
  allow! if permission_action.subject == :attachment
44
44
 
45
45
  permission_action
@@ -180,8 +180,8 @@ module Decidim
180
180
  allow!
181
181
  end
182
182
 
183
- def share_tokens_action?
184
- return unless permission_action.subject == :share_tokens
183
+ def share_token_action?
184
+ return unless permission_action.subject == :share_token
185
185
 
186
186
  allow!
187
187
  end
@@ -214,10 +214,7 @@ module Decidim
214
214
 
215
215
  def allowed_to_send_to_technical_validation?
216
216
  initiative.discarded? ||
217
- (initiative.created? && (
218
- !initiative.created_by_individual? ||
219
- initiative.enough_committee_members?
220
- ))
217
+ (initiative.created? && initiative.enough_committee_members?)
221
218
  end
222
219
  end
223
220
  end
@@ -15,12 +15,14 @@ module Decidim
15
15
  read_public_initiative?
16
16
  search_initiative_types_and_scopes?
17
17
  request_membership?
18
+ ephemeral_vote_initiative?
18
19
 
19
20
  return permission_action unless user
20
21
 
21
22
  create_initiative?
22
23
  edit_public_initiative?
23
24
  update_public_initiative?
25
+ discard_initiative?
24
26
  print_initiative?
25
27
 
26
28
  vote_initiative?
@@ -89,11 +91,17 @@ module Decidim
89
91
  toggle_allow(initiative&.created? && authorship_or_admin?)
90
92
  end
91
93
 
94
+ def discard_initiative?
95
+ return unless permission_action.subject == :initiative &&
96
+ permission_action.action == :discard
97
+
98
+ toggle_allow(initiative&.created? && authorship_or_admin?)
99
+ end
100
+
92
101
  def creation_enabled?
93
102
  Decidim::Initiatives.creation_enabled && (
94
103
  Decidim::Initiatives.do_not_require_authorization ||
95
- UserAuthorizations.for(user).any? ||
96
- Decidim::UserGroups::ManageableUserGroups.for(user).verified.any?) &&
104
+ UserAuthorizations.for(user).any?) &&
97
105
  authorized?(:create, permissions_holder: initiative_type)
98
106
  end
99
107
 
@@ -120,8 +128,7 @@ module Decidim
120
128
  !initiative.has_authorship?(user) &&
121
129
  (
122
130
  Decidim::Initiatives.do_not_require_authorization ||
123
- UserAuthorizations.for(user).any? ||
124
- Decidim::UserGroups::ManageableUserGroups.for(user).verified.any?
131
+ UserAuthorizations.for(user).any?
125
132
  )
126
133
  end
127
134
 
@@ -143,6 +150,14 @@ module Decidim
143
150
  toggle_allow(can_vote?)
144
151
  end
145
152
 
153
+ def ephemeral_vote_initiative?
154
+ return unless permission_action.action == :vote &&
155
+ permission_action.subject == :initiative &&
156
+ user.blank?
157
+
158
+ toggle_allow(ephemeral_signature_workflow?)
159
+ end
160
+
146
161
  def authorized?(permission_action, resource: nil, permissions_holder: nil)
147
162
  return unless resource || permissions_holder
148
163
 
@@ -155,8 +170,7 @@ module Decidim
155
170
 
156
171
  can_unvote = initiative.accepts_online_unvotes? &&
157
172
  initiative.organization&.id == user.organization&.id &&
158
- initiative.votes.where(author: user).any? &&
159
- authorized?(:vote, resource: initiative, permissions_holder: initiative.type)
173
+ initiative.votes.where(author: user).any?
160
174
 
161
175
  toggle_allow(can_unvote)
162
176
  end
@@ -178,15 +192,10 @@ module Decidim
178
192
  toggle_allow(can_sign)
179
193
  end
180
194
 
181
- def decidim_user_group_id
182
- context.fetch(:group_id, nil)
183
- end
184
-
185
195
  def can_vote?
186
196
  initiative.votes_enabled? &&
187
197
  initiative.organization&.id == user.organization&.id &&
188
- initiative.votes.where(author: user).empty? &&
189
- authorized?(:vote, resource: initiative, permissions_holder: initiative.type)
198
+ initiative.votes.where(author: user).empty?
190
199
  end
191
200
 
192
201
  def can_user_support?(initiative)
@@ -226,15 +235,16 @@ module Decidim
226
235
  end
227
236
 
228
237
  def allowed_to_send_to_technical_validation?
229
- initiative.created? && (
230
- !initiative.created_by_individual? ||
231
- initiative.enough_committee_members?
232
- )
238
+ initiative.created? && initiative.enough_committee_members?
233
239
  end
234
240
 
235
241
  def authorship_or_admin?
236
242
  initiative&.has_authorship?(user) || user.admin?
237
243
  end
244
+
245
+ def ephemeral_signature_workflow?
246
+ initiative.type.signature_workflow_manifest&.ephemeral?
247
+ end
238
248
  end
239
249
  end
240
250
  end
@@ -4,13 +4,19 @@ module Decidim
4
4
  #
5
5
  # Decorator for initiatives
6
6
  #
7
- class InitiativePresenter < SimpleDelegator
7
+ class InitiativePresenter < Decidim::ResourcePresenter
8
8
  def author
9
- @author ||= if user_group
10
- Decidim::UserGroupPresenter.new(user_group)
11
- else
12
- Decidim::UserPresenter.new(super)
13
- end
9
+ @author ||= super.presenter
10
+ end
11
+
12
+ def initiative
13
+ __getobj__
14
+ end
15
+
16
+ def title(html_escape: false, all_locales: false)
17
+ return unless initiative
18
+
19
+ super(initiative.title, html_escape, all_locales)
14
20
  end
15
21
  end
16
22
  end
@@ -31,8 +31,7 @@ module Decidim
31
31
  signature_start_date: :date,
32
32
  signature_end_date: :date,
33
33
  description: :i18n,
34
- title: :i18n,
35
- hashtag: :string
34
+ title: :i18n
36
35
  }
37
36
  end
38
37
 
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Initiatives
5
+ # This class counts all Followers of a initiative
6
+ class InitiativesStatsFollowersCount < Decidim::StatsFollowersCount
7
+ def self.for(participatory_space)
8
+ return 0 unless participatory_space.is_a?(Decidim::Initiatives)
9
+
10
+ new(participatory_space).query
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Initiatives
5
+ # This class counts unique Participants on a initiative
6
+ class InitiativesStatsParticipantsCount < Decidim::StatsParticipantsCount
7
+ def self.for(participatory_space)
8
+ return 0 unless participatory_space.is_a?(Decidim::Initiatives)
9
+
10
+ new(participatory_space).query
11
+ end
12
+ end
13
+ end
14
+ end
@@ -24,7 +24,6 @@ module Decidim
24
24
  answer: resource.answer,
25
25
  answered_at: resource.answered_at,
26
26
  answer_url: resource.answer_url,
27
- hashtag: resource.hashtag,
28
27
  first_progress_notification_at: resource.first_progress_notification_at,
29
28
  second_progress_notification_at: resource.second_progress_notification_at,
30
29
  online_votes: resource.online_votes,
@@ -8,7 +8,7 @@ module Decidim
8
8
 
9
9
  def initialize(args = {})
10
10
  @secret = args.fetch(:secret) || "default"
11
- @key = ActiveSupport::KeyGenerator.new(secret).generate_key(
11
+ @key = ActiveSupport::KeyGenerator.new(secret, hash_digest_class: OpenSSL::Digest::SHA1).generate_key(
12
12
  Rails.application.secret_key_base, ActiveSupport::MessageEncryptor.key_len
13
13
  )
14
14
  @encryptor = ActiveSupport::MessageEncryptor.new(@key)
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Initiatives
5
+ # Signature handler which reproduces the old feature of
6
+ # `collect_personal_data` of initiative types. The handler will collect the
7
+ # name and surname, the document number and the date of birth
8
+ class LegacySignatureHandler < SignatureHandler
9
+ attribute :name_and_surname, String
10
+ attribute :document_number, String
11
+ attribute :date_of_birth, Date
12
+ attribute :postal_code, String
13
+
14
+ validates :name_and_surname, :document_number, :date_of_birth, :postal_code, presence: true
15
+
16
+ def unique_id
17
+ document_number
18
+ end
19
+
20
+ def metadata
21
+ super.merge(name_and_surname:, document_number:, date_of_birth:, postal_code:)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -12,15 +12,9 @@ module Decidim
12
12
 
13
13
  # PUBLIC: Notifies the support progress of the initiative.
14
14
  #
15
- # Notifies to Initiative's authors and followers about the
15
+ # Notifies to Initiative's authors about the
16
16
  # number of supports received by the initiative.
17
17
  def notify
18
- initiative.followers.each do |follower|
19
- Decidim::Initiatives::InitiativesMailer
20
- .notify_progress(initiative, follower)
21
- .deliver_later
22
- end
23
-
24
18
  initiative.committee_members.approved.each do |committee_member|
25
19
  Decidim::Initiatives::InitiativesMailer
26
20
  .notify_progress(initiative, committee_member.user)