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.
- checksums.yaml +4 -4
- data/README.md +46 -9
- data/app/cells/decidim/initiatives/content_blocks/highlighted_initiatives_settings_form/show.erb +7 -2
- data/app/cells/decidim/initiatives/initiative_g_cell.rb +5 -1
- data/app/commands/decidim/initiatives/admin/publish_initiative.rb +1 -5
- data/app/commands/decidim/initiatives/admin/update_initiative.rb +1 -2
- data/app/commands/decidim/initiatives/create_initiative.rb +0 -1
- data/app/commands/decidim/initiatives/update_initiative.rb +1 -3
- data/app/commands/decidim/initiatives/vote_initiative.rb +1 -11
- data/app/controllers/concerns/decidim/initiatives/has_signature_workflow.rb +36 -0
- data/app/controllers/concerns/decidim/initiatives/needs_initiative.rb +1 -12
- data/app/controllers/decidim/initiatives/admin/initiatives_controller.rb +2 -2
- data/app/controllers/decidim/initiatives/admin/initiatives_settings_controller.rb +1 -1
- data/app/controllers/decidim/initiatives/admin/initiatives_type_scopes_controller.rb +2 -2
- data/app/controllers/decidim/initiatives/admin/initiatives_types_controller.rb +2 -2
- data/app/controllers/decidim/initiatives/committee_requests_controller.rb +10 -2
- data/app/controllers/decidim/initiatives/create_initiative_controller.rb +84 -18
- data/app/controllers/decidim/initiatives/initiative_signatures_controller.rb +133 -42
- data/app/controllers/decidim/initiatives/initiative_votes_controller.rb +3 -2
- data/app/controllers/decidim/initiatives/initiatives_controller.rb +21 -2
- data/app/forms/decidim/initiatives/admin/initiative_form.rb +0 -1
- data/app/forms/decidim/initiatives/initiative_form.rb +0 -3
- data/app/helpers/decidim/initiatives/application_helper.rb +2 -0
- data/app/helpers/decidim/initiatives/initiatives_helper.rb +0 -1
- data/app/models/decidim/initiative.rb +7 -31
- data/app/models/decidim/initiatives_committee_member.rb +1 -1
- data/app/models/decidim/initiatives_type.rb +5 -2
- data/app/models/decidim/initiatives_vote.rb +2 -2
- data/app/packs/entrypoints/decidim_initiatives.js +1 -1
- data/app/packs/entrypoints/decidim_initiatives_admin.scss +1 -1
- data/app/packs/src/decidim/initiatives/admin/initiatives_types.js +2 -11
- data/app/packs/src/decidim/initiatives/admin/invite_users.js +1 -1
- data/app/packs/src/decidim/initiatives/application.js +1 -1
- data/app/packs/src/decidim/initiatives/check_code.js +114 -0
- data/app/packs/src/decidim/initiatives/initiative_creation_wizard.js +16 -0
- data/app/packs/src/decidim/initiatives/scoped_type.js +1 -1
- data/app/packs/stylesheets/initiatives.scss +16 -2
- data/app/permissions/decidim/initiatives/admin/permissions.rb +4 -7
- data/app/permissions/decidim/initiatives/permissions.rb +26 -16
- data/app/presenters/decidim/initiative_presenter.rb +12 -6
- data/app/presenters/decidim/initiatives/admin_log/initiative_presenter.rb +1 -2
- data/app/queries/decidim/initiatives/initiatives_stats_followers_count.rb +14 -0
- data/app/queries/decidim/initiatives/initiatives_stats_participants_count.rb +14 -0
- data/app/serializers/decidim/initiatives/open_data_initiative_serializer.rb +0 -1
- data/app/services/decidim/initiatives/data_encryptor.rb +1 -1
- data/app/services/decidim/initiatives/legacy_signature_handler.rb +25 -0
- data/app/services/decidim/initiatives/progress_notifier.rb +1 -7
- data/app/services/decidim/initiatives/signature_handler.rb +248 -0
- data/app/services/decidim/initiatives/status_change_notifier.rb +1 -7
- data/app/views/decidim/initiatives/admin/committee_requests/index.html.erb +29 -11
- data/app/views/decidim/initiatives/admin/exports/_dropdown.html.erb +17 -20
- data/app/views/decidim/initiatives/admin/initiatives/_form.html.erb +7 -13
- data/app/views/decidim/initiatives/admin/initiatives/_initiative_attachments.erb +2 -2
- data/app/views/decidim/initiatives/admin/initiatives/index.html.erb +76 -47
- data/app/views/decidim/initiatives/admin/initiatives_types/_form.html.erb +13 -21
- data/app/views/decidim/initiatives/admin/initiatives_types/_initiative_type_scopes.html.erb +28 -12
- data/app/views/decidim/initiatives/admin/initiatives_types/index.html.erb +33 -15
- data/app/views/decidim/initiatives/create_initiative/_committee_member.html.erb +27 -0
- data/app/views/decidim/initiatives/create_initiative/_return_to_initiatives_button.html.erb +3 -0
- data/app/views/decidim/initiatives/create_initiative/_send_to_technical_validation_button.html.erb +10 -0
- data/app/views/decidim/initiatives/create_initiative/_share_committee_link.html.erb +5 -1
- data/app/views/decidim/initiatives/create_initiative/fill_data.html.erb +7 -11
- data/app/views/decidim/initiatives/create_initiative/finish.html.erb +16 -13
- data/app/views/decidim/initiatives/create_initiative/promotal_committee.html.erb +33 -6
- data/app/views/decidim/initiatives/create_initiative/select_initiative_type.html.erb +40 -26
- data/app/views/decidim/initiatives/initiative_signatures/_sms_code_form.html.erb +22 -0
- data/app/views/decidim/initiatives/initiative_signatures/_sms_phone_number_form.html.erb +13 -0
- data/app/views/decidim/initiatives/initiative_signatures/fill_personal_data.html.erb +23 -22
- data/app/views/decidim/initiatives/initiative_signatures/finish.html.erb +17 -5
- data/app/views/decidim/initiatives/initiative_signatures/sms_code.html.erb +6 -8
- data/app/views/decidim/initiatives/initiative_signatures/sms_phone_number.html.erb +3 -8
- data/app/views/decidim/initiatives/initiative_signatures/update_buttons_and_counters.js.erb +3 -14
- data/app/views/decidim/initiatives/initiative_votes/update_buttons_and_counters.js.erb +3 -14
- data/app/views/decidim/initiatives/initiatives/_committee_members.html.erb +1 -1
- data/app/views/decidim/initiatives/initiatives/_form.html.erb +1 -3
- data/app/views/decidim/initiatives/initiatives/_new_initiative_button.html.erb +10 -3
- data/app/views/decidim/initiatives/initiatives/_pending_initiatives.html.erb +5 -0
- data/app/views/decidim/initiatives/initiatives/index.html.erb +8 -0
- data/app/views/decidim/initiatives/initiatives/show.html.erb +2 -2
- data/app/views/layouts/decidim/_initiative_signature_creation_header.html.erb +20 -2
- data/app/views/layouts/decidim/admin/_manage_initiatives.html.erb +1 -1
- data/app/views/layouts/decidim/initiative_signature_creation.html.erb +3 -1
- data/config/assets.rb +2 -2
- data/config/locales/ar.yml +0 -45
- data/config/locales/bg.yml +0 -54
- data/config/locales/ca-IT.yml +99 -51
- data/config/locales/ca.yml +99 -51
- data/config/locales/cs.yml +93 -54
- data/config/locales/de.yml +100 -52
- data/config/locales/el.yml +0 -45
- data/config/locales/en.yml +99 -51
- data/config/locales/es-MX.yml +99 -51
- data/config/locales/es-PY.yml +99 -51
- data/config/locales/es.yml +99 -51
- data/config/locales/eu.yml +120 -72
- data/config/locales/fi-plain.yml +99 -51
- data/config/locales/fi.yml +99 -51
- data/config/locales/fr-CA.yml +44 -51
- data/config/locales/fr.yml +44 -51
- data/config/locales/ga-IE.yml +0 -17
- data/config/locales/gl.yml +0 -41
- data/config/locales/hu.yml +0 -54
- data/config/locales/id-ID.yml +0 -40
- data/config/locales/is-IS.yml +0 -22
- data/config/locales/it.yml +0 -53
- data/config/locales/ja.yml +98 -49
- data/config/locales/lb.yml +0 -50
- data/config/locales/lt.yml +0 -56
- data/config/locales/lv.yml +0 -46
- data/config/locales/nl.yml +0 -47
- data/config/locales/no.yml +0 -53
- data/config/locales/pl.yml +0 -56
- data/config/locales/pt-BR.yml +0 -53
- data/config/locales/pt.yml +0 -53
- data/config/locales/ro-RO.yml +92 -50
- data/config/locales/ru.yml +0 -25
- data/config/locales/sk.yml +0 -43
- data/config/locales/sl.yml +0 -1
- data/config/locales/sv.yml +10 -53
- data/config/locales/tr-TR.yml +0 -53
- data/config/locales/uk.yml +0 -25
- data/config/locales/zh-CN.yml +0 -45
- data/config/locales/zh-TW.yml +0 -53
- data/db/migrate/20250605104500_remove_hashtag_column_initiatives.rb +7 -0
- data/lib/decidim/api/initiative_api_type.rb +3 -0
- data/lib/decidim/api/initiative_type.rb +23 -4
- data/lib/decidim/exporters/initiative_votes_pdf.rb +1 -1
- data/lib/decidim/initiatives/default_signature_authorizer.rb +17 -0
- data/lib/decidim/initiatives/engine.rb +17 -14
- data/lib/decidim/initiatives/menu.rb +1 -1
- data/lib/decidim/initiatives/participatory_space.rb +15 -1
- data/lib/decidim/initiatives/seeds.rb +1 -2
- data/lib/decidim/initiatives/signature_workflow_manifest.rb +176 -0
- data/lib/decidim/initiatives/signatures.rb +12 -0
- data/lib/decidim/initiatives/test/factories.rb +7 -7
- data/lib/decidim/initiatives/test/initiatives_signatures_test_helpers.rb +19 -0
- data/lib/decidim/initiatives/validatable_authorizations.rb +83 -0
- data/lib/decidim/initiatives/version.rb +1 -1
- data/lib/decidim/initiatives.rb +23 -12
- metadata +33 -21
- data/app/events/decidim/initiatives/endorse_initiative_event.rb +0 -13
- data/app/forms/decidim/initiatives/vote_form.rb +0 -208
- data/app/packs/src/decidim/initiatives/identity_selector_dialog.js +0 -14
- data/app/services/decidim/initiatives/pdf_signature_example.rb +0 -110
- data/app/views/decidim/initiatives/initiative_signatures/_wizard_steps.html.erb +0 -15
- data/app/views/decidim/initiatives/initiatives/_interactions.html.erb +0 -10
- 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-
|
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
|
-
|
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
|
184
|
-
return unless permission_action.subject == :
|
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 <
|
7
|
+
class InitiativePresenter < Decidim::ResourcePresenter
|
8
8
|
def author
|
9
|
-
@author ||=
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
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
|
@@ -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
|
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)
|