decidim-proposals 0.27.5 → 0.27.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/cells/decidim/proposals/highlighted_proposals_for_component/show.erb +1 -1
- data/app/cells/decidim/proposals/participatory_text_proposal/buttons.erb +2 -2
- data/app/cells/decidim/proposals/proposal_tags/show.erb +2 -2
- data/app/controllers/decidim/proposals/widgets_controller.rb +11 -1
- data/app/helpers/decidim/proposals/application_helper.rb +1 -1
- data/app/models/decidim/proposals/proposal.rb +2 -14
- data/app/models/decidim/proposals/valuation_assignment.rb +2 -1
- data/app/packs/src/decidim/proposals/admin/proposals.js +7 -0
- data/app/permissions/decidim/proposals/permissions.rb +9 -0
- data/app/presenters/decidim/proposals/admin_log/proposal_presenter.rb +1 -5
- data/app/presenters/decidim/proposals/admin_log/value_types/proposal_title_body_presenter.rb +1 -3
- data/app/presenters/decidim/proposals/log/valuation_assignment_presenter.rb +1 -1
- data/app/views/decidim/proposals/admin/proposals/_form.html.erb +1 -1
- data/app/views/decidim/proposals/admin/proposals/_proposal-tr.html.erb +1 -1
- data/app/views/decidim/proposals/admin/proposals/show.html.erb +1 -1
- data/app/views/decidim/proposals/admin/proposals/update_attribute.js.erb +2 -1
- data/app/views/decidim/proposals/proposals/show.html.erb +3 -1
- data/config/locales/ar.yml +2 -6
- data/config/locales/bg.yml +748 -1
- data/config/locales/ca.yml +35 -33
- data/config/locales/cs.yml +5 -4
- data/config/locales/de.yml +9 -7
- data/config/locales/el.yml +0 -4
- data/config/locales/en.yml +2 -0
- data/config/locales/es-MX.yml +9 -7
- data/config/locales/es-PY.yml +9 -7
- data/config/locales/es.yml +22 -20
- data/config/locales/eu.yml +6 -4
- data/config/locales/fi-plain.yml +7 -5
- data/config/locales/fi.yml +6 -4
- data/config/locales/fr-CA.yml +9 -7
- data/config/locales/fr.yml +9 -7
- data/config/locales/ga-IE.yml +13 -0
- data/config/locales/gl.yml +2 -5
- data/config/locales/he-IL.yml +1 -0
- data/config/locales/hu.yml +16 -11
- data/config/locales/id-ID.yml +1 -4
- data/config/locales/is-IS.yml +4 -5
- data/config/locales/it.yml +4 -7
- data/config/locales/ja.yml +19 -17
- data/config/locales/lt.yml +0 -4
- data/config/locales/lv.yml +1 -4
- data/config/locales/nl.yml +5 -8
- data/config/locales/no.yml +1 -4
- data/config/locales/pl.yml +91 -5
- data/config/locales/pt-BR.yml +34 -5
- data/config/locales/pt.yml +1 -4
- data/config/locales/ro-RO.yml +1 -3
- data/config/locales/ru.yml +7 -5
- data/config/locales/sk.yml +5 -8
- data/config/locales/sv.yml +3 -7
- data/config/locales/tr-TR.yml +9 -8
- data/config/locales/uk.yml +7 -5
- data/config/locales/zh-CN.yml +1 -4
- data/config/locales/zh-TW.yml +0 -4
- data/db/migrate/20240404202756_add_valuation_assignments_count_to_decidim_proposals_proposals.rb +16 -0
- data/decidim-proposals.gemspec +40 -0
- data/lib/decidim/proposals/proposal_serializer.rb +52 -0
- data/lib/decidim/proposals/test/factories.rb +76 -57
- data/lib/decidim/proposals/valuatable.rb +2 -1
- data/lib/decidim/proposals/version.rb +1 -1
- metadata +26 -25
- data/app/presenters/decidim/proposals/log/resource_presenter.rb +0 -22
- data/config/environment.rb +0 -3
data/config/locales/sv.yml
CHANGED
@@ -171,7 +171,6 @@ sv:
|
|
171
171
|
proposal_wizard_step_1_help_text: Hjälptext till steget "Skapa" i förslagsguiden
|
172
172
|
proposal_wizard_step_2_help_text: Hjälptext till steget "Jämför" i förslagsguiden
|
173
173
|
proposal_wizard_step_3_help_text: Hjälptext till steget "Komplettera" i förslagsguiden
|
174
|
-
proposal_wizard_step_4_help_text: Förslagsguidens hjälptext för steg "Publicera"
|
175
174
|
resources_permissions_enabled: Åtgärdsbehörigheter kan ställas in för varje förslag
|
176
175
|
scope_id: Omfång
|
177
176
|
scopes_enabled: Omfång aktiverade
|
@@ -257,7 +256,6 @@ sv:
|
|
257
256
|
notification_title: Ditt förslag <a href="%{resource_path}">%{resource_title}</a> har accepterats.
|
258
257
|
follower:
|
259
258
|
email_intro: 'Förslaget "%{resource_title}" har accepterats. Läs svaret på den här sidan:'
|
260
|
-
email_outro: Du har fått det här meddelandet eftersom du följer "%{resource_title}". Du kan sluta att följa det via föregående länk.
|
261
259
|
email_subject: Ett förslag som du följer har accepterats
|
262
260
|
notification_title: Förslaget <a href="%{resource_path}">%{resource_title}</a> har accepterats.
|
263
261
|
proposal_evaluating:
|
@@ -268,7 +266,6 @@ sv:
|
|
268
266
|
notification_title: Ditt förslag <a href="%{resource_path}">%{resource_title}</a> utvärderas.
|
269
267
|
follower:
|
270
268
|
email_intro: 'Förslaget "%{resource_title}" utvärderas för närvarande. Du kan söka efter ett svar på den här sidan:'
|
271
|
-
email_outro: Du har fått det här meddelandet eftersom du följer "%{resource_title}". Du kan sluta att följa det via föregående länk.
|
272
269
|
email_subject: Ett förslag som du följer utvärderas
|
273
270
|
notification_title: Förslaget <a href="%{resource_path}">%{resource_title}</a> utvärderas.
|
274
271
|
proposal_mentioned:
|
@@ -293,7 +290,6 @@ sv:
|
|
293
290
|
notification_title: Ditt förslag <a href="%{resource_path}">%{resource_title}</a> har avslagits.
|
294
291
|
follower:
|
295
292
|
email_intro: 'Förslaget "%{resource_title}" har avslagits. Du kan läsa svaret på den här sidan:'
|
296
|
-
email_outro: Du har fått det här meddelandet eftersom du följer "%{resource_title}". Du kan sluta att följa det via föregående länk.
|
297
293
|
email_subject: Ett förslag som du följer har avslagits
|
298
294
|
notification_title: Förslaget <a href="%{resource_path}">%{resource_title}</a> har avslagits.
|
299
295
|
proposal_update_category:
|
@@ -436,7 +432,7 @@ sv:
|
|
436
432
|
accepted: Accepterat
|
437
433
|
answer_proposal: Svara
|
438
434
|
evaluating: Utvärderas
|
439
|
-
not_answered: Ej
|
435
|
+
not_answered: Ej besvarat
|
440
436
|
rejected: Avvisat
|
441
437
|
title: Svar på förslaget %{title}
|
442
438
|
proposal_notes:
|
@@ -581,11 +577,11 @@ sv:
|
|
581
577
|
filter_scope_values:
|
582
578
|
all: Alla
|
583
579
|
filter_state_values:
|
584
|
-
accepted:
|
580
|
+
accepted: Accepterat
|
585
581
|
all: Alla
|
586
582
|
evaluating: Utvärderas
|
587
583
|
not_answered: Ej besvarade
|
588
|
-
rejected:
|
584
|
+
rejected: Avvisat
|
589
585
|
filter_type_values:
|
590
586
|
all: Alla
|
591
587
|
amendments: Ändringsförslag
|
data/config/locales/tr-TR.yml
CHANGED
@@ -143,7 +143,7 @@ tr:
|
|
143
143
|
proposal_wizard_step_1_help_text: Teklif sihirbazı "Oluştur" adımı yardım metni
|
144
144
|
proposal_wizard_step_2_help_text: Teklif sihirbazı "Karşılaştır" adımı yardım metni
|
145
145
|
proposal_wizard_step_3_help_text: Teklif sihirbazı "Tamamlandı" adımı yardım metni
|
146
|
-
proposal_wizard_step_4_help_text: Teklif
|
146
|
+
proposal_wizard_step_4_help_text: Teklif "Yayınlama" sihirbazı yardım metni
|
147
147
|
resources_permissions_enabled: Her teklif için işlem izinleri ayarlanabilir
|
148
148
|
scope_id: Kapsam
|
149
149
|
scopes_enabled: Kapsamlar etkinleştirildi
|
@@ -217,7 +217,7 @@ tr:
|
|
217
217
|
notification_title: Teklifiniz <a href="%{resource_path}">%{resource_title}</a> kabul edildi.
|
218
218
|
follower:
|
219
219
|
email_intro: '"%{resource_title}" teklifi kabul edildi. Cevabı bu sayfada okuyabilirsiniz:'
|
220
|
-
email_outro: Bu bildirimi
|
220
|
+
email_outro: Bu bildirimi "%{resource_title}" adresini takip ettiğiniz için aldınız. Önceki bağlantıdan takibi bırakabilirsiniz.
|
221
221
|
email_subject: Takip ettiğiniz bir teklif kabul edildi
|
222
222
|
notification_title: <a href="%{resource_path}">%{resource_title}</a> teklif kabul edildi.
|
223
223
|
proposal_evaluating:
|
@@ -228,7 +228,7 @@ tr:
|
|
228
228
|
notification_title: Teklifiniz <a href="%{resource_path}">%{resource_title}</a> değerlendiriliyor.
|
229
229
|
follower:
|
230
230
|
email_intro: 'Şu anda "%{resource_title}" teklifi değerlendiriliyor. Bu sayfadaki cevabı kontrol edebilirsiniz:'
|
231
|
-
email_outro: Bu bildirimi
|
231
|
+
email_outro: Bu bildirimi "%{resource_title}" adresini takip ettiğiniz için aldınız. Önceki bağlantıdan takibi bırakabilirsiniz.
|
232
232
|
email_subject: Takip ettiğiniz bir teklif değerlendiriliyor
|
233
233
|
notification_title: <a href="%{resource_path}">%{resource_title}</a> teklifi değerlendiriliyor.
|
234
234
|
proposal_mentioned:
|
@@ -252,7 +252,7 @@ tr:
|
|
252
252
|
notification_title: Teklifiniz <a href="%{resource_path}">%{resource_title}</a> reddedildi.
|
253
253
|
follower:
|
254
254
|
email_intro: '"%{resource_title}" teklifi reddedildi. Cevabı bu sayfada okuyabilirsiniz:'
|
255
|
-
email_outro: Bu bildirimi
|
255
|
+
email_outro: Bu bildirimi "%{resource_title}" adresini takip ettiğiniz için aldınız. Önceki bağlantıdan takibi bırakabilirsiniz.
|
256
256
|
email_subject: Takip ettiğiniz bir teklif reddedildi
|
257
257
|
notification_title: <a href="%{resource_path}">%{resource_title}</a> teklifi reddedildi.
|
258
258
|
proposal_update_category:
|
@@ -381,10 +381,11 @@ tr:
|
|
381
381
|
success: Katılımcı metin başarıyla güncellendi.
|
382
382
|
proposal_answers:
|
383
383
|
form:
|
384
|
-
accepted: Kabul
|
384
|
+
accepted: Kabul Edildi
|
385
385
|
answer_proposal: Cevap
|
386
|
-
evaluating:
|
387
|
-
|
386
|
+
evaluating: Değerlendiriliyor
|
387
|
+
not_answered: Cevaplanmadı
|
388
|
+
rejected: Reddedildi
|
388
389
|
title: Teklifin cevabı %{title}
|
389
390
|
proposal_notes:
|
390
391
|
create:
|
@@ -817,7 +818,7 @@ tr:
|
|
817
818
|
wizard_aside:
|
818
819
|
back: Geri
|
819
820
|
back_from_step_1: Teklifte geri dön
|
820
|
-
back_from_step_2:
|
821
|
+
back_from_step_2: Teklifte geri dön
|
821
822
|
back_from_step_3: Teklifleri karşılaştırmaya geri dön
|
822
823
|
back_from_step_4: Taslağı düzenlemeye dön
|
823
824
|
info: <strong>teklif</strong>.
|
data/config/locales/uk.yml
CHANGED
@@ -8,6 +8,7 @@ uk:
|
|
8
8
|
body: Основний текст
|
9
9
|
category_id: Категорія
|
10
10
|
has_address: Має адресу
|
11
|
+
scope_id: Обсяг
|
11
12
|
state: Стан
|
12
13
|
title: Назва
|
13
14
|
user_group_id: Створити пропозицію як
|
@@ -82,7 +83,6 @@ uk:
|
|
82
83
|
proposal_wizard_step_1_help_text: Довідка майстра пропозицій щодо кроку "Створити"
|
83
84
|
proposal_wizard_step_2_help_text: Довідка майстра пропозицій щодо кроку "Порівняти"
|
84
85
|
proposal_wizard_step_3_help_text: Довідка майстра пропозицій щодо кроку "Завершити"
|
85
|
-
proposal_wizard_step_4_help_text: Довідка майстра пропозицій щодо кроку "Оприлюднити"
|
86
86
|
resources_permissions_enabled: Для кожної пропозиції можна встановити ті чи інші дозволи на дії
|
87
87
|
threshold_per_proposal: Поріг на кожну пропозицію
|
88
88
|
vote_limit: Гранична кількість голосів від одного учасника
|
@@ -110,13 +110,11 @@ uk:
|
|
110
110
|
proposal_accepted:
|
111
111
|
follower:
|
112
112
|
email_intro: 'Пропозиція "%{resource_title}" була прийнята. Ви можете прочитати відповідь на сторінці:'
|
113
|
-
email_outro: Ви отримали це сповіщення, тому що ви стежите за "%{resource_title}". Ви можете припинити стежити за ним, перейшовши за наведеним вище посиланням.
|
114
113
|
email_subject: Пропозиція, за якою ви стежите, була прийнята
|
115
114
|
notification_title: Пропозицію <a href="%{resource_path}">%{resource_title}</a> було прийнято.
|
116
115
|
proposal_evaluating:
|
117
116
|
follower:
|
118
117
|
email_intro: 'Пропозиція "%{resource_title}" зараз розглядається. Ви можете перевірити наявність відповіді на сторінці:'
|
119
|
-
email_outro: Ви отримали це сповіщення, тому що ви стежите за "%{resource_title}". Ви можете припинити стежити за ним, перейшовши за наведеним вище посиланням.
|
120
118
|
email_subject: Пропозиція, за якою ви стежите, зараз розглядається
|
121
119
|
notification_title: Пропозиція <a href="%{resource_path}">%{resource_title}</a> розглядається.
|
122
120
|
proposal_mentioned:
|
@@ -131,7 +129,6 @@ uk:
|
|
131
129
|
proposal_rejected:
|
132
130
|
follower:
|
133
131
|
email_intro: 'Пропозиція "%{resource_title}" була відхилена. Ви можете прочитати відповідь на сторінці:'
|
134
|
-
email_outro: Ви отримали це сповіщення, тому що ви стежите за "%{resource_title}". Ви можете припинити стежити за ним, перейшовши за наведеним вище посиланням.
|
135
132
|
email_subject: Пропозиція, за якою ви стежите, була відхилена
|
136
133
|
notification_title: Пропозицію <a href="%{resource_path}">%{resource_title}</a> було відхилено.
|
137
134
|
proposal_update_category:
|
@@ -164,6 +161,7 @@ uk:
|
|
164
161
|
accepted: Прийнято
|
165
162
|
answer_proposal: Відповісти
|
166
163
|
evaluating: Розглядається
|
164
|
+
not_answered: Без відповідей
|
167
165
|
rejected: Відхилено
|
168
166
|
title: Відповідь на пропозицію %{title}
|
169
167
|
proposal_notes:
|
@@ -230,7 +228,10 @@ uk:
|
|
230
228
|
filter_origin_values:
|
231
229
|
official: Службове
|
232
230
|
filter_state_values:
|
231
|
+
accepted: Прийнято
|
232
|
+
evaluating: Розглядається
|
233
233
|
not_answered: Без відповідей
|
234
|
+
rejected: Відхилено
|
234
235
|
content_blocks:
|
235
236
|
highlighted_proposals:
|
236
237
|
proposals: Пропозиції
|
@@ -269,7 +270,6 @@ uk:
|
|
269
270
|
no_similars_found: Гарна робота! Не знайдено схожий пропозицій
|
270
271
|
title: Подібні пропозиції
|
271
272
|
complete:
|
272
|
-
send: Надіслати
|
273
273
|
title: Завершіть свою пропозицію
|
274
274
|
edit:
|
275
275
|
attachment_legend: "(Необов'язково) Додати вкладений файл"
|
@@ -283,6 +283,7 @@ uk:
|
|
283
283
|
send: Попередній перегляд
|
284
284
|
title: Редагувати чернетку пропозиції
|
285
285
|
filters:
|
286
|
+
all: Усі
|
286
287
|
category: Категорія
|
287
288
|
origin: Джерело
|
288
289
|
related_to: Пов'язане з
|
@@ -355,6 +356,7 @@ uk:
|
|
355
356
|
vote_limit:
|
356
357
|
description: Ви можете проголосувати до %{limit} пропозицій.
|
357
358
|
left: Залишилось
|
359
|
+
votes: Голоси
|
358
360
|
wizard_aside:
|
359
361
|
back: Повернутись
|
360
362
|
info: Ви вносите <strong>пропозицію</strong>.
|
data/config/locales/zh-CN.yml
CHANGED
@@ -136,7 +136,6 @@ zh-CN:
|
|
136
136
|
proposal_wizard_step_1_help_text: 建议向导“创建”步骤帮助文本
|
137
137
|
proposal_wizard_step_2_help_text: 建议向导“Compare”步骤帮助文本
|
138
138
|
proposal_wizard_step_3_help_text: 建议向导“完成”步骤帮助文本
|
139
|
-
proposal_wizard_step_4_help_text: 建议向导"发布"步骤帮助文本
|
140
139
|
resources_permissions_enabled: 每个提案都可以设置动作权限
|
141
140
|
scope_id: 范围
|
142
141
|
scopes_enabled: 范围已启用
|
@@ -206,7 +205,6 @@ zh-CN:
|
|
206
205
|
notification_title: 您的提议 <a href="%{resource_path}">%{resource_title}</a> 已被接受。
|
207
206
|
follower:
|
208
207
|
email_intro: '提议 "%{resource_title}" 已被接受。您可以在此页面中阅读答案:'
|
209
|
-
email_outro: 您收到此通知是因为您正在关注 "%{resource_title}"。您可以从上一个链接取消关注它。
|
210
208
|
email_subject: 您关注的建议已被接受
|
211
209
|
notification_title: <a href="%{resource_path}">%{resource_title}</a> 提议已被接受。
|
212
210
|
proposal_evaluating:
|
@@ -217,7 +215,6 @@ zh-CN:
|
|
217
215
|
notification_title: 您的提议 <a href="%{resource_path}">%{resource_title}</a> 正在评估中。
|
218
216
|
follower:
|
219
217
|
email_intro: '提议 "%{resource_title}" 目前正在评估。您可以在这个页面检查答案:'
|
220
|
-
email_outro: 您收到此通知是因为您正在关注 "%{resource_title}"。您可以从上一个链接取消关注它。
|
221
218
|
email_subject: 正在评估您关注的建议
|
222
219
|
notification_title: <a href="%{resource_path}">%{resource_title}</a> 提议正在评估中。
|
223
220
|
proposal_mentioned:
|
@@ -239,7 +236,6 @@ zh-CN:
|
|
239
236
|
notification_title: 您的提议 <a href="%{resource_path}">%{resource_title}</a> 已被拒绝
|
240
237
|
follower:
|
241
238
|
email_intro: '提议 "%{resource_title}" 已被拒绝。您可以在此页中读取答案:'
|
242
|
-
email_outro: 您收到此通知是因为您正在关注 "%{resource_title}"。您可以从上一个链接取消关注它。
|
243
239
|
email_subject: 您关注的建议已被拒绝
|
244
240
|
notification_title: <a href="%{resource_path}">%{resource_title}</a> 提议已被拒绝。
|
245
241
|
proposal_update_category:
|
@@ -366,6 +362,7 @@ zh-CN:
|
|
366
362
|
accepted: 已接受
|
367
363
|
answer_proposal: 答案
|
368
364
|
evaluating: 评价
|
365
|
+
not_answered: 未回答
|
369
366
|
rejected: 已拒绝
|
370
367
|
title: 对提议 %{title} 的答案
|
371
368
|
proposal_notes:
|
data/config/locales/zh-TW.yml
CHANGED
@@ -171,7 +171,6 @@ zh-TW:
|
|
171
171
|
proposal_wizard_step_1_help_text: 提案向導「創建」步驟說明文字
|
172
172
|
proposal_wizard_step_2_help_text: 提案向導「比較」步驟說明文字
|
173
173
|
proposal_wizard_step_3_help_text: 提案向導「完成」步驟說明文字
|
174
|
-
proposal_wizard_step_4_help_text: 提案向導「發佈」步驟說明文字
|
175
174
|
resources_permissions_enabled: 每個提案都可以設定行動權限
|
176
175
|
scope_id: 範圍
|
177
176
|
scopes_enabled: 啟用範圍
|
@@ -271,7 +270,6 @@ zh-TW:
|
|
271
270
|
notification_title: 您的提案 <a href="%{resource_path}">%{resource_title}</a> 已被接受。
|
272
271
|
follower:
|
273
272
|
email_intro: '該提案「%{resource_title}」已被接受。您可以在此頁面上閱讀回應:'
|
274
|
-
email_outro: 您收到了此通知,是因為您正在關注 "%{resource_title}"。您可以通過前面的鏈接取消關注它。
|
275
273
|
email_subject: 您追蹤的提案已被接受
|
276
274
|
notification_title: <a href="%{resource_path}">%{resource_title}</a>" 提案已經被接受。
|
277
275
|
proposal_evaluating:
|
@@ -282,7 +280,6 @@ zh-TW:
|
|
282
280
|
notification_title: 您的提案<a href="%{resource_path}">%{resource_title}</a>正在評估中。
|
283
281
|
follower:
|
284
282
|
email_intro: '該提案“%{resource_title}”正在進行評估。您可以在此頁面上查看答案:'
|
285
|
-
email_outro: 您收到了此通知,是因為您正在關注 "%{resource_title}"。您可以通過前面的鏈接取消關注它。
|
286
283
|
email_subject: 你追蹤的提案正在評估中
|
287
284
|
notification_title: <a href="%{resource_path}">%{resource_title}</a> 提案正在評估中。
|
288
285
|
proposal_mentioned:
|
@@ -309,7 +306,6 @@ zh-TW:
|
|
309
306
|
notification_title: 您的提案<a href="%{resource_path}">%{resource_title}</a>已被拒絕。
|
310
307
|
follower:
|
311
308
|
email_intro: '該提案「%{resource_title}」已被駁回。您可以在此頁面中閱讀回覆:'
|
312
|
-
email_outro: 您收到了此通知,是因為您正在關注 "%{resource_title}"。您可以通過前面的鏈接取消關注它。
|
313
309
|
email_subject: 您追蹤的提案已被拒絕
|
314
310
|
notification_title: <a href="%{resource_path}">%{resource_title}</a>" 提案已經被拒絕。
|
315
311
|
proposal_update_category:
|
data/db/migrate/20240404202756_add_valuation_assignments_count_to_decidim_proposals_proposals.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class AddValuationAssignmentsCountToDecidimProposalsProposals < ActiveRecord::Migration[6.1]
|
4
|
+
def change
|
5
|
+
add_column :decidim_proposals_proposals, :valuation_assignments_count, :integer, default: 0
|
6
|
+
|
7
|
+
reversible do |dir|
|
8
|
+
dir.up do
|
9
|
+
Decidim::Proposals::Proposal.reset_column_information
|
10
|
+
Decidim::Proposals::Proposal.find_each do |record|
|
11
|
+
Decidim::Proposals::Proposal.reset_counters(record.id, :valuation_assignments)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
$LOAD_PATH.push File.expand_path("lib", __dir__)
|
4
|
+
|
5
|
+
# Maintain your gem's version:
|
6
|
+
require "decidim/proposals/version"
|
7
|
+
|
8
|
+
# Describe your gem and declare its dependencies:
|
9
|
+
Gem::Specification.new do |s|
|
10
|
+
s.version = Decidim::Proposals.version
|
11
|
+
s.authors = ["Josep Jaume Rey Peroy", "Marc Riera Casals", "Oriol Gual Oliva"]
|
12
|
+
s.email = ["josepjaume@gmail.com", "mrc2407@gmail.com", "oriolgual@gmail.com"]
|
13
|
+
s.license = "AGPL-3.0"
|
14
|
+
s.homepage = "https://github.com/decidim/decidim"
|
15
|
+
s.required_ruby_version = "~> 3.0.0"
|
16
|
+
|
17
|
+
s.name = "decidim-proposals"
|
18
|
+
s.summary = "Decidim proposals module"
|
19
|
+
s.description = "A proposals component for decidim's participatory spaces."
|
20
|
+
|
21
|
+
s.files = Dir.chdir(__dir__) do
|
22
|
+
`git ls-files -z`.split("\x0").select do |f|
|
23
|
+
(File.expand_path(f) == __FILE__) ||
|
24
|
+
f.start_with?(*%w(app/ config/ db/ lib/ Rakefile README.md))
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
s.add_dependency "decidim-comments", Decidim::Proposals.version
|
29
|
+
s.add_dependency "decidim-core", Decidim::Proposals.version
|
30
|
+
s.add_dependency "doc2text", "~> 0.4.5"
|
31
|
+
s.add_dependency "redcarpet", "~> 3.5", ">= 3.5.1"
|
32
|
+
|
33
|
+
s.add_development_dependency "decidim-admin", Decidim::Proposals.version
|
34
|
+
s.add_development_dependency "decidim-assemblies", Decidim::Proposals.version
|
35
|
+
s.add_development_dependency "decidim-budgets", Decidim::Proposals.version
|
36
|
+
s.add_development_dependency "decidim-conference", Decidim::Proposals.version
|
37
|
+
s.add_development_dependency "decidim-dev", Decidim::Proposals.version
|
38
|
+
s.add_development_dependency "decidim-meetings", Decidim::Proposals.version
|
39
|
+
s.add_development_dependency "decidim-participatory_processes", Decidim::Proposals.version
|
40
|
+
end
|
@@ -19,6 +19,9 @@ module Decidim
|
|
19
19
|
def serialize
|
20
20
|
{
|
21
21
|
id: proposal.id,
|
22
|
+
author: {
|
23
|
+
**author_fields
|
24
|
+
},
|
22
25
|
category: {
|
23
26
|
id: proposal.category.try(:id),
|
24
27
|
name: proposal.category.try(:name) || empty_translatable
|
@@ -40,6 +43,7 @@ module Decidim
|
|
40
43
|
state: proposal.state.to_s,
|
41
44
|
reference: proposal.reference,
|
42
45
|
answer: ensure_translatable(proposal.answer),
|
46
|
+
answered_at: proposal.answered_at,
|
43
47
|
supports: proposal.proposal_votes_count,
|
44
48
|
endorsements: {
|
45
49
|
total_count: proposal.endorsements.size,
|
@@ -101,6 +105,54 @@ module Decidim
|
|
101
105
|
|
102
106
|
convert_to_text(value)
|
103
107
|
end
|
108
|
+
|
109
|
+
def author_fields
|
110
|
+
is_author_user_group = resource.coauthorships.map(&:decidim_user_group_id).any?
|
111
|
+
|
112
|
+
{
|
113
|
+
id: resource.authors.map(&:id),
|
114
|
+
name: resource.authors.map do |author|
|
115
|
+
author_name(is_author_user_group ? resource.coauthorships.first.user_group : author)
|
116
|
+
end,
|
117
|
+
url: resource.authors.map do |author|
|
118
|
+
author_url(is_author_user_group ? resource.coauthorships.first.user_group : author)
|
119
|
+
end
|
120
|
+
}
|
121
|
+
end
|
122
|
+
|
123
|
+
def author_name(author)
|
124
|
+
if author.respond_to?(:name)
|
125
|
+
translated_attribute(author.name) # is a Decidim::User or Decidim::Organization or Decidim::UserGroup
|
126
|
+
elsif author.respond_to?(:title)
|
127
|
+
translated_attribute(author.title) # is a Decidim::Meetings::Meeting
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def author_url(author)
|
132
|
+
if author.respond_to?(:nickname)
|
133
|
+
profile_url(author.nickname) # is a Decidim::User or Decidim::UserGroup
|
134
|
+
elsif author.respond_to?(:title)
|
135
|
+
meeting_url(author) # is a Decidim::Meetings::Meeting
|
136
|
+
else
|
137
|
+
root_url # is a Decidim::Organization
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def profile_url(nickname)
|
142
|
+
Decidim::Core::Engine.routes.url_helpers.profile_url(nickname, host: host)
|
143
|
+
end
|
144
|
+
|
145
|
+
def meeting_url(meeting)
|
146
|
+
Decidim::EngineRouter.main_proxy(meeting.component).meeting_url(id: meeting.id, host: host)
|
147
|
+
end
|
148
|
+
|
149
|
+
def root_url
|
150
|
+
Decidim::Core::Engine.routes.url_helpers.root_url(host: host)
|
151
|
+
end
|
152
|
+
|
153
|
+
def host
|
154
|
+
resource.organization.host
|
155
|
+
end
|
104
156
|
end
|
105
157
|
end
|
106
158
|
end
|
@@ -6,10 +6,12 @@ require "decidim/meetings/test/factories"
|
|
6
6
|
|
7
7
|
FactoryBot.define do
|
8
8
|
factory :proposal_component, parent: :component do
|
9
|
-
|
9
|
+
transient do
|
10
|
+
skip_injection { false }
|
11
|
+
end
|
12
|
+
name { generate_component_name(participatory_space.organization.available_locales, :proposals) }
|
10
13
|
manifest_name { :proposals }
|
11
|
-
participatory_space { create(:participatory_process, :with_steps, organization: organization) }
|
12
|
-
|
14
|
+
participatory_space { create(:participatory_process, :with_steps, organization: organization, skip_injection: skip_injection) }
|
13
15
|
trait :with_endorsements_enabled do
|
14
16
|
step_settings do
|
15
17
|
{
|
@@ -250,28 +252,16 @@ FactoryBot.define do
|
|
250
252
|
skip_injection { false }
|
251
253
|
end
|
252
254
|
|
253
|
-
title
|
254
|
-
|
255
|
-
|
256
|
-
else
|
257
|
-
Decidim::Faker::Localized.localized { "<script>alert(\"TITLE\");</script> #{generate(:title)}" }
|
258
|
-
end
|
259
|
-
end
|
260
|
-
body do
|
261
|
-
if skip_injection
|
262
|
-
Decidim::Faker::Localized.localized { Faker::Lorem.sentences(number: 3).join("\n") }
|
263
|
-
else
|
264
|
-
Decidim::Faker::Localized.localized { "<script>alert(\"TITLE\");</script> #{Faker::Lorem.sentences(number: 3).join("\n")}" }
|
265
|
-
end
|
266
|
-
end
|
267
|
-
component { create(:proposal_component) }
|
255
|
+
title { generate_localized_title(:proposal_title, skip_injection: skip_injection) }
|
256
|
+
body { generate_localized_description(:proposal_body, skip_injection: skip_injection) }
|
257
|
+
component { create(:proposal_component, skip_injection: skip_injection) }
|
268
258
|
published_at { Time.current }
|
269
259
|
address { "#{Faker::Address.street_name}, #{Faker::Address.city}" }
|
270
260
|
latitude { Faker::Address.latitude }
|
271
261
|
longitude { Faker::Address.longitude }
|
272
262
|
cost { 20_000 }
|
273
|
-
cost_report {
|
274
|
-
execution_period {
|
263
|
+
cost_report { generate_localized_title(:proposal_cost_report, skip_injection: skip_injection) }
|
264
|
+
execution_period { generate_localized_title(:proposal_execution_period, skip_injection: skip_injection) }
|
275
265
|
|
276
266
|
after(:build) do |proposal, evaluator|
|
277
267
|
proposal.title = if evaluator.title.is_a?(String)
|
@@ -289,7 +279,7 @@ FactoryBot.define do
|
|
289
279
|
proposal.body = Decidim::ContentProcessor.parse_with_processor(:hashtag, proposal.body, current_organization: proposal.organization).rewrite
|
290
280
|
|
291
281
|
if proposal.component
|
292
|
-
users = evaluator.users || [create(:user, :confirmed, organization: proposal.component.participatory_space.organization)]
|
282
|
+
users = evaluator.users || [create(:user, :confirmed, organization: proposal.component.participatory_space.organization, skip_injection: evaluator.skip_injection)]
|
293
283
|
users.each_with_index do |user, idx|
|
294
284
|
user_group = evaluator.user_groups[idx]
|
295
285
|
proposal.coauthorships.build(author: user, user_group: user_group)
|
@@ -306,18 +296,18 @@ FactoryBot.define do
|
|
306
296
|
end
|
307
297
|
|
308
298
|
trait :participant_author do
|
309
|
-
after :build do |proposal|
|
299
|
+
after :build do |proposal, evaluator|
|
310
300
|
proposal.coauthorships.clear
|
311
|
-
user = build(:user, organization: proposal.component.participatory_space.organization)
|
301
|
+
user = build(:user, organization: proposal.component.participatory_space.organization, skip_injection: evaluator.skip_injection)
|
312
302
|
proposal.coauthorships.build(author: user)
|
313
303
|
end
|
314
304
|
end
|
315
305
|
|
316
306
|
trait :user_group_author do
|
317
|
-
after :build do |proposal|
|
307
|
+
after :build do |proposal, evaluator|
|
318
308
|
proposal.coauthorships.clear
|
319
|
-
user = create(:user, organization: proposal.component.participatory_space.organization)
|
320
|
-
user_group = create(:user_group, :verified, organization: user.organization, users: [user])
|
309
|
+
user = create(:user, organization: proposal.component.participatory_space.organization, skip_injection: evaluator.skip_injection)
|
310
|
+
user_group = create(:user_group, :verified, organization: user.organization, users: [user], skip_injection: evaluator.skip_injection)
|
321
311
|
proposal.coauthorships.build(author: user, user_group: user_group)
|
322
312
|
end
|
323
313
|
end
|
@@ -330,10 +320,10 @@ FactoryBot.define do
|
|
330
320
|
end
|
331
321
|
|
332
322
|
trait :official_meeting do
|
333
|
-
after :build do |proposal|
|
323
|
+
after :build do |proposal, evaluator|
|
334
324
|
proposal.coauthorships.clear
|
335
|
-
component = build(:meeting_component, participatory_space: proposal.component.participatory_space)
|
336
|
-
proposal.coauthorships.build(author: build(:meeting, component: component))
|
325
|
+
component = build(:meeting_component, participatory_space: proposal.component.participatory_space, skip_injection: evaluator.skip_injection)
|
326
|
+
proposal.coauthorships.build(author: build(:meeting, component: component, skip_injection: evaluator.skip_injection))
|
337
327
|
end
|
338
328
|
end
|
339
329
|
|
@@ -382,78 +372,101 @@ FactoryBot.define do
|
|
382
372
|
end
|
383
373
|
|
384
374
|
trait :hidden do
|
385
|
-
after :create do |proposal|
|
386
|
-
create(:moderation, hidden_at: Time.current, reportable: proposal)
|
375
|
+
after :create do |proposal, evaluator|
|
376
|
+
create(:moderation, hidden_at: Time.current, reportable: proposal, skip_injection: evaluator.skip_injection)
|
387
377
|
end
|
388
378
|
end
|
389
379
|
|
390
380
|
trait :with_votes do
|
391
|
-
after :create do |proposal|
|
392
|
-
create_list(:proposal_vote, 5, proposal: proposal)
|
381
|
+
after :create do |proposal, evaluator|
|
382
|
+
create_list(:proposal_vote, 5, proposal: proposal, skip_injection: evaluator.skip_injection)
|
393
383
|
end
|
394
384
|
end
|
395
385
|
|
396
386
|
trait :with_endorsements do
|
397
|
-
after :create do |proposal|
|
387
|
+
after :create do |proposal, evaluator|
|
398
388
|
5.times.collect do
|
399
|
-
create(:endorsement, resource: proposal,
|
389
|
+
create(:endorsement, resource: proposal, skip_injection: evaluator.skip_injection,
|
390
|
+
author: build(:user, organization: proposal.participatory_space.organization, skip_injection: evaluator.skip_injection))
|
400
391
|
end
|
401
392
|
end
|
402
393
|
end
|
403
394
|
|
404
395
|
trait :with_amendments do
|
405
|
-
after :create do |proposal|
|
406
|
-
create_list(:proposal_amendment, 5, amendable: proposal)
|
396
|
+
after :create do |proposal, evaluator|
|
397
|
+
create_list(:proposal_amendment, 5, amendable: proposal, skip_injection: evaluator.skip_injection)
|
407
398
|
end
|
408
399
|
end
|
409
400
|
|
410
401
|
trait :with_photo do
|
411
|
-
after :create do |proposal|
|
412
|
-
proposal.attachments << create(:attachment, :with_image, attached_to: proposal)
|
402
|
+
after :create do |proposal, evaluator|
|
403
|
+
proposal.attachments << create(:attachment, :with_image, attached_to: proposal, skip_injection: evaluator.skip_injection)
|
413
404
|
end
|
414
405
|
end
|
415
406
|
|
416
407
|
trait :with_document do
|
417
|
-
after :create do |proposal|
|
418
|
-
proposal.attachments << create(:attachment, :with_pdf, attached_to: proposal)
|
408
|
+
after :create do |proposal, evaluator|
|
409
|
+
proposal.attachments << create(:attachment, :with_pdf, attached_to: proposal, skip_injection: evaluator.skip_injection)
|
410
|
+
end
|
411
|
+
end
|
412
|
+
|
413
|
+
trait :moderated do
|
414
|
+
after(:create) do |proposal, evaluator|
|
415
|
+
create(:moderation, reportable: proposal, hidden_at: 2.days.ago, skip_injection: evaluator.skip_injection)
|
419
416
|
end
|
420
417
|
end
|
421
418
|
end
|
422
419
|
|
423
420
|
factory :proposal_vote, class: "Decidim::Proposals::ProposalVote" do
|
424
|
-
|
425
|
-
|
421
|
+
transient do
|
422
|
+
skip_injection { false }
|
423
|
+
end
|
424
|
+
proposal { build(:proposal, skip_injection: skip_injection) }
|
425
|
+
author { build(:user, organization: proposal.organization, skip_injection: skip_injection) }
|
426
426
|
end
|
427
427
|
|
428
428
|
factory :proposal_amendment, class: "Decidim::Amendment" do
|
429
|
-
|
430
|
-
|
431
|
-
|
429
|
+
transient do
|
430
|
+
skip_injection { false }
|
431
|
+
end
|
432
|
+
amendable { build(:proposal, skip_injection: skip_injection) }
|
433
|
+
emendation { build(:proposal, component: amendable.component, skip_injection: skip_injection) }
|
434
|
+
amender { build(:user, organization: amendable.component.participatory_space.organization, skip_injection: skip_injection) }
|
432
435
|
state { Decidim::Amendment::STATES.sample }
|
433
436
|
end
|
434
437
|
|
435
438
|
factory :proposal_note, class: "Decidim::Proposals::ProposalNote" do
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
+
transient do
|
440
|
+
skip_injection { false }
|
441
|
+
end
|
442
|
+
body do
|
443
|
+
if skip_injection
|
444
|
+
generate(:title)
|
445
|
+
else
|
446
|
+
"<script>alert(\"proposal_note_body\");</script> #{generate(:title)}"
|
447
|
+
end
|
448
|
+
end
|
449
|
+
proposal { build(:proposal, skip_injection: skip_injection) }
|
450
|
+
author { build(:user, organization: proposal.organization, skip_injection: skip_injection) }
|
439
451
|
end
|
440
452
|
|
441
453
|
factory :collaborative_draft, class: "Decidim::Proposals::CollaborativeDraft" do
|
442
454
|
transient do
|
443
455
|
users { nil }
|
456
|
+
skip_injection { false }
|
444
457
|
# user_groups correspondence to users is by sorting order
|
445
458
|
user_groups { [] }
|
446
459
|
end
|
447
460
|
|
448
|
-
title {
|
449
|
-
body {
|
450
|
-
component { create(:proposal_component) }
|
461
|
+
title { generate_localized_title(:collaborative_draft_title, skip_injection: skip_injection)["en"] }
|
462
|
+
body { generate_localized_description(:collaborative_draft_body, skip_injection: skip_injection)["en"] }
|
463
|
+
component { create(:proposal_component, skip_injection: skip_injection) }
|
451
464
|
address { "#{Faker::Address.street_name}, #{Faker::Address.city}" }
|
452
465
|
state { "open" }
|
453
466
|
|
454
467
|
after(:build) do |collaborative_draft, evaluator|
|
455
468
|
if collaborative_draft.component
|
456
|
-
users = evaluator.users || [create(:user, organization: collaborative_draft.component.participatory_space.organization)]
|
469
|
+
users = evaluator.users || [create(:user, organization: collaborative_draft.component.participatory_space.organization, skip_injection: evaluator.skip_injection)]
|
457
470
|
users.each_with_index do |user, idx|
|
458
471
|
user_group = evaluator.user_groups[idx]
|
459
472
|
collaborative_draft.coauthorships.build(author: user, user_group: user_group)
|
@@ -476,17 +489,23 @@ FactoryBot.define do
|
|
476
489
|
end
|
477
490
|
|
478
491
|
factory :participatory_text, class: "Decidim::Proposals::ParticipatoryText" do
|
479
|
-
|
480
|
-
|
481
|
-
|
492
|
+
transient do
|
493
|
+
skip_injection { false }
|
494
|
+
end
|
495
|
+
title { generate_localized_title(:participatory_text_title, skip_injection: skip_injection) }
|
496
|
+
description { generate_localized_description(:participatory_text_description, skip_injection: skip_injection) }
|
497
|
+
component { create(:proposal_component, skip_injection: skip_injection) }
|
482
498
|
end
|
483
499
|
|
484
500
|
factory :valuation_assignment, class: "Decidim::Proposals::ValuationAssignment" do
|
501
|
+
transient do
|
502
|
+
skip_injection { false }
|
503
|
+
end
|
485
504
|
proposal
|
486
505
|
valuator_role do
|
487
506
|
space = proposal.component.participatory_space
|
488
507
|
organization = space.organization
|
489
|
-
build :participatory_process_user_role, role: :valuator, user: build(:user, organization: organization)
|
508
|
+
build :participatory_process_user_role, role: :valuator, skip_injection: skip_injection, user: build(:user, organization: organization, skip_injection: skip_injection)
|
490
509
|
end
|
491
510
|
end
|
492
511
|
end
|
@@ -8,7 +8,8 @@ module Decidim
|
|
8
8
|
include Decidim::Comments::Commentable
|
9
9
|
|
10
10
|
included do
|
11
|
-
has_many :valuation_assignments, foreign_key: "decidim_proposal_id", dependent: :destroy
|
11
|
+
has_many :valuation_assignments, foreign_key: "decidim_proposal_id", dependent: :destroy,
|
12
|
+
counter_cache: :valuation_assignments_count, class_name: "Decidim::Proposals::ValuationAssignment"
|
12
13
|
|
13
14
|
def valuators
|
14
15
|
valuator_role_ids = valuation_assignments.where(proposal: self).pluck(:valuator_role_id)
|