<%= present(@proposal).title(links: true, html_escape: true) %>
<% unless component_settings.participatory_texts_enabled? %>
diff --git a/decidim-proposals/config/locales/ar.yml b/decidim-proposals/config/locales/ar.yml
index 7b544194c69e2..ce56c8eb2b48e 100644
--- a/decidim-proposals/config/locales/ar.yml
+++ b/decidim-proposals/config/locales/ar.yml
@@ -158,7 +158,6 @@ ar:
participatory_texts_enabled: تم تمكين النصوص التشاركية
participatory_texts_enabled_readonly: لا يمكن التفاعل مع هذا الإعداد إذا كانت هناك اقتراحات موجودة. الرجاء إنشاء "مكون مقترحات" جديد إذا كنت ترغب في تمكين هذه الميزة أو تجاهل كافة المقترحات المستوردة في قائمة "النصوص التشاركية" إذا كنت ترغب في تعطيلها.
proposal_answering_enabled: تم تمكين الرد على الاقتراح
- proposal_edit_before_minutes: يمكن تحرير المقترحات من قبل المؤلفين قبل مرور عدة دقائق
proposal_edit_time: تحرير المقترح
proposal_edit_time_choices:
infinite: السماح بتعديل المقترحات لفترة زمنية غير محدودة
@@ -406,7 +405,6 @@ ar:
form:
note: ملحوظة
submit: خضع
- leave_your_note: اترك ملاحظتك
title: ملاحظات خاصة
proposals:
edit:
diff --git a/decidim-proposals/config/locales/bg.yml b/decidim-proposals/config/locales/bg.yml
index 0ad5cc52ef239..51586b4be2f5e 100644
--- a/decidim-proposals/config/locales/bg.yml
+++ b/decidim-proposals/config/locales/bg.yml
@@ -179,7 +179,6 @@ bg:
participatory_texts_enabled: Текстовете от участници са разрешени
participatory_texts_enabled_readonly: Тази настройка не е активна, ако има съществуващи предложения. Моля, създайте нов компонент „Предложения“, ако желаете да активирате тази функция или изчистете всички внесени предложения в менюто „Текст на участници“, ако искате да я деактивирате.
proposal_answering_enabled: Отговора на предложение е разрешен
- proposal_edit_before_minutes: Предложенията могат да бъдат редактирани от авторите преди да минат толкова минути
proposal_edit_time: Редактиране на предложение
proposal_edit_time_choices:
infinite: Разрешаване на редактиране на предложения за безкраен период от време
@@ -235,10 +234,8 @@ bg:
proposals:
admin:
proposal_note_created:
- email_intro: Някой е направил бележка в предложението %{resource_title}. Вижте я в
администраторския панел.
email_outro: Получихте известие, защото можете да оценяте предложението.
email_subject: Някой е направил бележка в предложението %{resource_title}.
- notification_title: Някой е направил бележка в предложението
%{resource_title}. Вижте я в
администраторския панел.
collaborative_draft_access_accepted:
email_intro: '%{requester_name} получи достъп като сътрудник в съвместната чернова
%{resource_title}.'
email_outro: Получихте известие, защото сте сътрудник в
%{resource_title}.
@@ -473,7 +470,6 @@ bg:
form:
note: Бележка
submit: Подаване
- leave_your_note: Оставете Вашата бележка
title: Лични бележки
proposal_states:
create:
diff --git a/decidim-proposals/config/locales/ca.yml b/decidim-proposals/config/locales/ca.yml
index 1534f82942858..b8648a31ee9e3 100644
--- a/decidim-proposals/config/locales/ca.yml
+++ b/decidim-proposals/config/locales/ca.yml
@@ -170,6 +170,11 @@ ca:
random: Aleatòriament
recent: Recents
with_more_authors: Amb més autores
+ edit_time: Les autores poden editar les seves propostes abans que passi aquest temps
+ edit_time_units:
+ days: Dies
+ hours: Hores
+ minutes: Minuts
geocoding_enabled: Geocodificació habilitada
minimum_votes_per_user: Suports mínims per usuari
new_proposal_body_template: Plantilla pel text de nova proposta
@@ -179,11 +184,14 @@ ca:
participatory_texts_enabled: Texts participatius habilitats
participatory_texts_enabled_readonly: No es pot interactuar amb aquesta configuració si hi ha propostes existents. Si us plau, crea un nou 'component de propostes' si vols habilitar aquesta característica o descarta totes les propostes importades al menú "textos participatius" si vols deshabilitar-lo.
proposal_answering_enabled: Resposta a propostes habilitada
- proposal_edit_before_minutes: Les propostes poden ser editades per les autores abans que passin aquests minuts
proposal_edit_time: Edició de propostes
proposal_edit_time_choices:
infinite: Permet l'edició de propostes durant un període infinit
limited: Permet l'edició de propostes durant una finestra temporal específica
+ proposal_edit_time_unit_options:
+ days: Dies
+ hours: Hores
+ minutes: Minuts
proposal_length: Longitud màxima del cos de la proposta
proposal_limit: Límit de propostes per participant
proposal_wizard_step_1_help_text: Text d'ajuda pel pas "Crear" de l'assistent de propostes
@@ -234,11 +242,26 @@ ca:
events:
proposals:
admin:
+ proposal_assigned_to_valuator:
+ email_intro: Has estat assignada com a avaluadora de la proposta "%{resource_title}". Això vol dir que es confia en tu per donar la teva opinió i per donar una resposta adequada en els pròxims dies. Pots veure la proposta al
taulell d'administració.
+ email_outro: Reps aquesta notificació perquè pots avaluar la proposta.
+ email_subject: Has estat assignada com a avaluadora de la proposta "%{resource_title}".
+ notification_title: Has estat assignada com a avaluadora de la proposta "
%{resource_title}". Pots veure la proposta al
taulell d'administració.
proposal_note_created:
- email_intro: Algú ha deixat una nota a la proposta "%{resource_title}". Revisa-la ara a través del
taulell d'administració.
+ email_intro: '%{author_name} ha creat una nota privada a %{resource_title}. La pots veure al
taulell d''administració.'
email_outro: Reps aquesta notificació perquè pots avaluar la proposta.
email_subject: Algú ha deixat una nota a la proposta %{resource_title}.
- notification_title: Algú ha deixat una nota a la proposta
%{resource_title}. Revisa-la ara a través del
taulell d'administració.
+ notification_title:
%{author_name} %{author_nickname} ha creat una nota privada a
%{resource_title}. La pots veure al
taulell d'administració.
+ proposal_note_mentioned:
+ email_intro: '"%{author_name}" "%{author_nickname}" t''ha esmentat a una nota privada a "%{resource_title}". La pots veure al
taulell d''administració.'
+ email_outro: Has rebut aquesta notificació perquè t'han esmentat a una nota privada.
+ email_subject: Algú ha deixat una nota a la proposta %{resource_title}.
+ notification_title:
%{author_name} %{author_nickname} te ha esmentat a una nota privada a
%{resource_title}. La pots veure al
taulell d'administració.
+ proposal_note_replied:
+ email_intro: '%{author_name} ha respost la teva nota privada a %{resource_title}. Ho pots veure al
taulell d''administració.'
+ email_outro: Has rebut aquesta notificació perquè ets l'autora de la nota privada.
+ email_subject: "%{author_name} ha respost a la teva nota privada a %{resource_title}."
+ notification_title:
%{author_name} %{author_nickname} ha respost a la teva nota privada a
%{resource_title}. Ho pots veure al
taulell d'administració.
collaborative_draft_access_accepted:
email_intro: 'S''ha acceptat %{requester_name} per accedir com a contribuidora de l''esborrany col·laboratiu
%{resource_title}.'
email_outro: Has rebut aquesta notificació perquè vas contribuir a la proposta "
%{resource_title}".
@@ -473,7 +496,9 @@ ca:
form:
note: Nota
submit: Enviar
- leave_your_note: Deixa la teva nota
+ reply:
+ error: S'ha produït un error en crear aquesta resposta a la nota privada.
+ success: La resposta a la nota privada s'ha creat amb èxit.
title: Notes privades
proposal_states:
create:
diff --git a/decidim-proposals/config/locales/cs.yml b/decidim-proposals/config/locales/cs.yml
index 2d3510a702e8f..365c9e9fd13cf 100644
--- a/decidim-proposals/config/locales/cs.yml
+++ b/decidim-proposals/config/locales/cs.yml
@@ -176,7 +176,6 @@ cs:
participatory_texts_enabled: Povolené účastnické texty
participatory_texts_enabled_readonly: Pokud existují stávající návrhy, nelze toto nastavení měnit. Pokud chcete tuto vlastnost povolit nebo vyhodit všechny importované návrhy v menu "participativní texty" prosím vytvořte novou složku "Návrhy", pokud ji chcete zakázat.
proposal_answering_enabled: Odpovídání návrhu je povoleno
- proposal_edit_before_minutes: Návrhy mohou být editovány autory před tím, než projde hodně minut
proposal_edit_time: Úprava návrhů
proposal_edit_time_choices:
infinite: Povolit úpravy návrhů na nekonečnou dobu
@@ -226,10 +225,8 @@ cs:
proposals:
admin:
proposal_note_created:
- email_intro: Někdo zanechal poznámku k návrhu "%{resource_title}". Podívejte se na
admin panel.
email_outro: Obdrželi jste toto oznámení, protože můžete návrh ohodnotit.
email_subject: Někdo zanechal poznámku na návrh %{resource_title}.
- notification_title: Někdo zanechal poznámku k návrhu
%{resource_title}. Podívejte se na
admin panel.
collaborative_draft_access_accepted:
email_intro: '%{requester_name} byl přijat k přístupu jako přispěvatel konceptu spolupráce
%{resource_title}.'
email_outro: Obdrželi jste toto oznámení, protože jste spolupracovníkem
%{resource_title}.
@@ -457,7 +454,6 @@ cs:
form:
note: Poznámka
submit: Předložit
- leave_your_note: Nechte svou poznámku
title: Soukromé poznámky
proposal_states:
create:
diff --git a/decidim-proposals/config/locales/de.yml b/decidim-proposals/config/locales/de.yml
index 355d651efd8cb..a8141c194ee45 100644
--- a/decidim-proposals/config/locales/de.yml
+++ b/decidim-proposals/config/locales/de.yml
@@ -52,7 +52,7 @@ de:
keep_authors: Behalten Sie die ursprünglichen Autoren
valuation_assignment:
admin_log:
- valuator_role_id: Name des Schätzers
+ valuator_role_id: Name des Bewertenden
errors:
models:
participatory_text:
@@ -128,7 +128,7 @@ de:
validating: Technische Validierung
withdrawn: Zurückgezogen
valuator_role_ids_has:
- label: Zugewiesen zu dem Schätzer
+ label: Zur Bewertung zugewiesen
with_any_state:
label: Beantwortet
values:
@@ -170,6 +170,11 @@ de:
random: Zufällig
recent: Neueste
with_more_authors: Mit mehr Autoren
+ edit_time: Vorschläge können vor Ablauf dieser Zeit von den Autoren bearbeitet werden
+ edit_time_units:
+ days: Tage
+ hours: Stunden
+ minutes: Minuten
geocoding_enabled: Geocoding aktiviert
minimum_votes_per_user: Minimal erforderliche Anzahl Stimmen eines Abstimmenden
new_proposal_body_template: Textvorlage für neuen Vorschlag
@@ -179,11 +184,14 @@ de:
participatory_texts_enabled: Partizipative Texte aktiviert
participatory_texts_enabled_readonly: Die Interaktion mit dieser Einstellung ist nicht möglich, wenn Vorschläge bestehen. Bitte erstellen Sie eine neue „Vorschlagskomponente“, wenn Sie diese Funktion aktivieren möchten, oder verwerfen Sie alle importierten Vorschläge im Menü „Beteiligungstexte“, wenn Sie diese Funktion deaktivieren möchten.
proposal_answering_enabled: Vorschlagsantworten aktiviert
- proposal_edit_before_minutes: Vorschläge können von Autoren innerhalb dieser Zeit bearbeitet werden
proposal_edit_time: Vorschläge bearbeiten
proposal_edit_time_choices:
infinite: Vorschläge können beliebig lang bearbeitet werden
limited: Vorschläge können nach einem spezifischen Zeitfenster nicht mehr bearbeitet werden
+ proposal_edit_time_unit_options:
+ days: Tage
+ hours: Stunden
+ minutes: Minuten
proposal_length: Maximale Länge des Haupttextes
proposal_limit: Vorschlagslimit pro Benutzer
proposal_wizard_step_1_help_text: Hilfetext "Erstellen"-Schritt im Vorschlagsassistenten
@@ -234,11 +242,26 @@ de:
events:
proposals:
admin:
+ proposal_assigned_to_valuator:
+ email_intro: Ihnen wurde der Vorschlag "%{resource_title}" zur Bewertung zugewiesen. Das bedeutet, dass von Ihnen in den nächsten Tagen eine Rückmeldung und Einschätzung erwartet wird. Jetzt
im Admin-Panel anschauen.
+ email_outro: Sie haben diese Benachrichtigung erhalten, weil Sie diesen Vorschlag bewerten können.
+ email_subject: Der Vorschlag %{resource_title} wurde Ihnen zur Bewertung zugewiesen.
+ notification_title: Ihnen wurde der Vorschlag
%{resource_title} zur Bewertung zugewiesen. Jetzt
Admin-Panel anschauen.
proposal_note_created:
- email_intro: Jemand hat eine Notiz zum Vorschlag "%{resource_title}" hinterlassen. Schauen Sie sie im
Admin-Panel an.
+ email_intro: '%{author_name} hat eine private Notiz unter %{resource_title} erstellt. Jetzt im
Admin-Panel anzeigen.'
email_outro: Sie haben diese Benachrichtigung erhalten, weil Sie diesen Vorschlag bewerten können.
email_subject: Jemand hat eine Notiz für Vorschlag %{resource_title} erstellt.
- notification_title: Jemand hat eine Notiz für den Vorschlag
%{resource_title}erstellt. Sie können sie über das
Admin-Panel anzeigen.
+ notification_title:
%{author_name} hat eine private Notiz unter
%{resource_title} erstellt. Jetzt im
Admin-Panel anzeigen.
+ proposal_note_mentioned:
+ email_intro: Sie wurden in einer privaten Notiz in "%{resource_title}" von "%{author_name}" "%{author_nickname}" erwähnt. Jetzt im
Admin-Panel anzeigen.
+ email_outro: Sie haben diese Benachrichtigung erhalten, weil Sie in einer privaten Notiz erwähnt wurden.
+ email_subject: Jemand hat Sie in einer Notiz zum Vorschlag "%{resource_title}" erwähnt.
+ notification_title: Sie wurden in einer privaten Notiz unter
"%{resource_title}" von
%{author_name} %{author_nickname} erwähnt. Jetzt im
Admin-Panel anzeigen.
+ proposal_note_replied:
+ email_intro: '%{author_name} hat deine private Notiz unter %{resource_title} beantwortet. Jetzt im
Admin-Panel anzeigen.'
+ email_outro: Sie haben diese Benachrichtigung erhalten, weil Sie der Autor der Noitz sind.
+ email_subject: "%{author_name} hat auf Ihre private Notiz unter %{resource_title} geantwortet."
+ notification_title:
%{author_name} hat Ihre private Notiz unter
%{resource_title} beantworter. Jetzt im
Admin-Panel anzeigen.
collaborative_draft_access_accepted:
email_intro: '%{requester_name} wurde zur Mitwirkung am kollaborativen Entwurf
%{resource_title} akzeptiert.'
email_outro: Sie haben diese Benachrichtigung erhalten, weil Sie bei
%{resource_title} mitwirken.
@@ -473,7 +496,9 @@ de:
form:
note: Anmerkung
submit: Absenden
- leave_your_note: Anmerkung hinterlassen
+ reply:
+ error: Beim Erstellen der Antwort zu dieser Vorschlagsnotiz ist ein Fehler aufgetreten.
+ success: Antwort auf die Vorschlagsnotiz erfolgreich erstellt.
title: Private Notizen
proposal_states:
create:
@@ -512,7 +537,7 @@ de:
select_a_meeting: Besprechung auswählen
index:
actions: Aktionen
- assign_to_valuator: Zuweisen zu dem Schätzer
+ assign_to_valuator: Zuweisen zur Bewertung
assign_to_valuator_button: Zuweisen
cancel: Abbrechen
change_category: Kategorie ändern
@@ -528,7 +553,7 @@ de:
split_button: Aufteilen
statuses: Status
title: Vorschläge
- unassign_from_valuator: Zuweisung an den Schätzer zurückziehen
+ unassign_from_valuator: Zuweisung zur Bewertung zurückziehen
unassign_from_valuator_button: Zuweisung aufheben
update: Aktualisieren
update_scope_button: Umfang aktualisieren
@@ -540,7 +565,7 @@ de:
select_a_proposal: Bitte wählen Sie einen Vorschlag.
show:
amendments_count: Anzahl der Ergänzungen
- assigned_valuators: Zugewiesene Schätzer
+ assigned_valuators: Zugewiesene Bewertende
body: Haupttext
comments_count: Anzahl der Kommentare
documents: Unterlagen
@@ -554,8 +579,8 @@ de:
ranking: "%{ranking} von %{total}"
related_meetings: Ähnliche Besprechungen
remove_assignment: Zuweisung entfernen
- remove_assignment_confirmation: Sind Sie sicher, diesen Schätzer von diesem Vorschlag zurückzuziehen?
- valuators: Schätzer
+ remove_assignment_confirmation: Sind Sie sicher, dass Sie den BewerterIn dieses Vorschlags entfernen möchten?
+ valuators: Bewertende
votes_count: Anzahl Stimmen
update_category:
invalid: 'Diese Vorschläge gehörten bereits zur Kategorie %{subject_name}: %{proposals}.'
@@ -587,11 +612,11 @@ de:
success: Die Vorschläge wurden erfolgreich in neue aufgeteilt.
valuation_assignments:
create:
- invalid: Bei der Zuweisung der Vorschläge an einen Schätzer ist ein Fehler aufgetreten.
- success: Die Vorschläge wurden erfolgreich dem Schätzer zugewiesen.
+ invalid: Bei der Zuweisung der Vorschläge zur Bewertung ist ein Fehler aufgetreten.
+ success: Die Vorschläge wurden erfolgreich zur Bewertung zugewiesen.
delete:
- invalid: Beim Zurückziehen der Zuweisung der Vorschläge an einen Schätzer ist ein Fehler aufgetreten.
- success: Die Zuweisung der Vorschläge wurden erfolgreich vom Schätzer zurückgezogen.
+ invalid: Beim Zurückziehen der Zuweisung der Vorschläge zur Bewertung ist ein Fehler aufgetreten.
+ success: Die Zuweisung zur Bewertung der Vorschläge wurde erfolgreich aufgehoben.
admin_log:
proposal:
answer: "%{user_name} beantwortete den %{resource_name} Vorschlag auf den %{space_name} Feldern"
@@ -601,8 +626,8 @@ de:
proposal_note:
create: "%{user_name} eine private Notiz zu dem %{resource_name} Vorschlag auf dem %{space_name} Feld hinterlassen"
valuation_assignment:
- create: "%{user_name} hat den Vorschlag %{resource_name} einem Schätzer zugewiesen"
- delete: "%{user_name} hat die Zuweisung vom Vorschlag %{proposal_title} von einem Schätzer zurückgezogen"
+ create: "%{user_name} hat den Vorschlag %{resource_name} zur Bewertung zugewiesen"
+ delete: "%{user_name} hat die Zuweisung zur Bewertung des Vorschlags %{proposal_title} zurückgezogen"
answers:
accepted: Angenommen
evaluating: In Bewertung
@@ -748,8 +773,8 @@ de:
scope: Umfang
state: Status
title: Titel
- valuator: Schätzer
- valuators: Schätzer
+ valuator: BewerterIn
+ valuators: Bewertende
votes: Stimmen
proposal_state:
css_class: CSS-Klasse
diff --git a/decidim-proposals/config/locales/el.yml b/decidim-proposals/config/locales/el.yml
index 5423fb6386076..c875d647c2ce7 100644
--- a/decidim-proposals/config/locales/el.yml
+++ b/decidim-proposals/config/locales/el.yml
@@ -152,7 +152,6 @@ el:
participatory_texts_enabled: Τα κείμενα συμμετοχής ενεργοποιήθηκαν
participatory_texts_enabled_readonly: Δεν είναι δυνατή η αλληλεπίδραση με αυτήν τη ρύθμιση αν διατίθενται υπάρχουσες προτάσεις. Δημιουργήστε ένα νέο «Στοιχείο προτάσεων» αν θέλετε να ενεργοποιήσετε αυτήν τη δυνατότητα ή απορρίψτε όλες τις προτάσεις που έχουν εισαχθεί από το μενού «Κείμενα συμμετοχής» αν θέλετε να την απενεργοποιήσετε.
proposal_answering_enabled: Η απάντηση στην πρόταση ενεργοποιήθηκε
- proposal_edit_before_minutes: Οι προτάσεις μπορούν να υποβληθούν σε επεξεργασία από συντάκτες προτού περάσουν αρκετά λεπτά
proposal_edit_time: Επεξεργασία πρότασης
proposal_edit_time_choices:
infinite: Επιτρέψτε την επεξεργασία προτάσεων για άπειρο χρονικό διάστημα
@@ -200,10 +199,8 @@ el:
proposals:
admin:
proposal_note_created:
- email_intro: Κάποιος άφησε μια σημείωση στην πρόταση "%{resource_title}". Ελέγξτε την στο
του πίνακα διαχείρισης.
email_outro: Λάβατε αυτήν την ειδοποίηση επειδή μπορείτε να εκτιμήσετε την πρόταση.
email_subject: Κάποιος άφησε μια σημείωση στην πρόταση %{resource_title}.
- notification_title: Κάποιος άφησε μια σημείωση στην πρόταση
%{resource_title}. Ελέγξτε την στο
πίνακα διαχείρισης.
collaborative_draft_access_accepted:
email_intro: '%{requester_name} έχει γίνει δεκτή η πρόσβαση ως συνεισφέρων του
%{resource_title} συνεργατικού σχεδίου.'
email_outro: Έχετε λάβει αυτήν την ειδοποίηση επειδή είστε συνεργάτης του
%{resource_title}.
@@ -404,7 +401,6 @@ el:
form:
note: Σημείωση
submit: Υποβολή
- leave_your_note: Αφήστε τη σημείωσή σας
title: Ιδιωτικές σημειώσεις
proposals:
answer:
diff --git a/decidim-proposals/config/locales/en.yml b/decidim-proposals/config/locales/en.yml
index 1f12b9ba567d3..e70ac357a51b5 100644
--- a/decidim-proposals/config/locales/en.yml
+++ b/decidim-proposals/config/locales/en.yml
@@ -176,7 +176,7 @@ en:
days: Days
hours: Hours
minutes: Minutes
- geocoding_enabled: Geocoding enabled
+ geocoding_enabled: Maps enabled
minimum_votes_per_user: Minimum votes per user
new_proposal_body_template: New proposal body template
new_proposal_body_template_help: You can define prefilled text that the new Proposals will have
@@ -242,6 +242,8 @@ en:
votes_hidden: Votes hidden (if votes are enabled, checking this will hide the number of votes)
events:
proposals:
+ accepted_coauthorship:
+ notification_title: You have been added as a co-author of the proposal
%{resource_title}.
admin:
proposal_assigned_to_valuator:
email_intro: You have been assigned as a valuator to the proposal "%{resource_title}". This means you have been trusted to give them feedback and a proper response in the next coming days. Check it out at
the admin panel.
@@ -263,6 +265,18 @@ en:
email_outro: You have received this notification because you are the author of the note.
email_subject: "%{author_name} has replied your private note in %{resource_title}."
notification_title:
%{author_name} %{author_nickname} has replied your private note in
%{resource_title}. Check it out at
the admin panel.
+ coauthor_accepted_invite:
+ notification_title:
%{coauthor_name} has accepted your invitation to become a co-author of the proposal
%{resource_title}.
+ coauthor_invited:
+ actions:
+ accept: Accept
+ decline: Decline
+ email_intro: 'You have been invited to be a co-author of the proposal "%{resource_title}". You can accept or decline the invitation in this page:'
+ email_outro: You have received this notification because the author of the proposal wants to recognize your contributions by becoming a co-author.
+ email_subject: You have been invited to be a co-author of the proposal "%{resource_title}"
+ notification_title:
%{author_name} would like to invite you as a co-author of the proposal
%{resource_title}.
+ coauthor_rejected_invite:
+ notification_title:
%{coauthor_name} has declined your invitation to become a co-author of the proposal
%{resource_title}.
collaborative_draft_access_accepted:
email_intro: '%{requester_name} has been accepted to access as a contributor of the
%{resource_title} collaborative draft.'
email_outro: You have received this notification because you are a collaborator of
%{resource_title}.
@@ -340,6 +354,8 @@ en:
email_outro: You have received this notification because you are the author of the proposal.
email_subject: The %{resource_title} proposal scope has been updated
notification_title: The
%{resource_title} proposal scope has been updated by an admin.
+ rejected_coauthorship:
+ notification_title: You have declined the invitation from
%{author_name} to become a co-author of the proposal
%{resource_title}.
voting_enabled:
email_intro: 'You can vote proposals in %{participatory_space_title}! Start participating in this page:'
email_outro: You have received this notification because you are following %{participatory_space_title}. You can stop receiving notifications following the previous link.
@@ -404,11 +420,15 @@ en:
proposals:
actions:
answer_proposal: Answer proposal
+ cancel_coauthor_invitation: Cancel co-author invitation
+ cancel_coauthor_invitation_confirm: Are you sure you want to cancel the co-author invitation?
delete_proposal_state_confirm: Are you sure you want to delete this state?
destroy: Delete state
edit_proposal: Edit proposal
edit_proposal_state: Edit state
import: Import proposals from another component
+ mark_as_coauthor: Mark as co-author
+ mark_as_coauthor_confirm: Are you sure you want to mark this user as a co-author? The receiver will receive a notification to accept or decline the invitation.
new: New proposal
new_proposal_state: New status
participatory_texts: Participatory texts
@@ -522,10 +542,12 @@ en:
success: Status updated successfully
proposals:
answer:
- invalid: There has been a problem answering this proposal.
+ bulk_answer_error: Proposals with IDs [%{proposals}] could not be answered due errors applying the template "%{template}". You can check that the answer template matches the expected format for this component by applying it individually.
+ bulk_answer_success: '%{count} proposals will be answered using the template "%{template}". Please wait a few minutes and refresh the page to see the updates.'
+ invalid: There was a problem answering this proposal.
success: Proposal successfully answered.
create:
- invalid: There has been a problem creating this proposal.
+ invalid: There was a problem creating this proposal.
success: Proposal successfully created.
edit:
title: Update proposal
@@ -538,6 +560,7 @@ en:
select_a_meeting: Select a meeting
index:
actions: Actions
+ apply_answer_template: Apply answer template
assign_to_valuator: Assign to valuator
assign_to_valuator_button: Assign
cancel: Cancel
@@ -545,6 +568,7 @@ en:
change_scope: Change scope
merge: Merge into a new one
merge_button: Merge
+ no_templates_available: No templates available
publish: Publish
publish_answers: Publish answers
select_component: Select a component
@@ -605,18 +629,18 @@ en:
title: Import proposals from another component
proposals_merges:
create:
- invalid: 'There has been a problem merging the selected proposals because some of them:'
+ invalid: 'There was a problem merging the selected proposals because some of them:'
success: Successfully merged the proposals into a new one.
proposals_splits:
create:
- invalid: 'There has been a problem splitting the selected proposals because some of them:'
+ invalid: 'There was a problem splitting the selected proposals because some of them:'
success: Successfully splitted the proposals into new ones.
valuation_assignments:
create:
- invalid: There was an error assigning proposals to a valuator.
+ invalid: There was a problem assigning proposals to a valuator.
success: Proposals assigned to a valuator successfully.
delete:
- invalid: There was an error unassigning proposals from a valuator.
+ invalid: There was a problem unassigning proposals from a valuator.
success: Valuator unassigned from proposals successfully.
admin_log:
proposal:
@@ -758,6 +782,19 @@ en:
destroy_draft:
error: There was a problem deleting the collaborative draft.
success: Proposal draft was successfully deleted.
+ invite_coauthors:
+ cancel:
+ error: There was a problem canceling the co-author invitation.
+ success: Co-author invitation successfully canceled.
+ create:
+ error: There was a problem inviting the co-author.
+ success: "%{author_name} successfully invited as a co-author."
+ destroy:
+ error: There was a problem declining the invitation.
+ success: The invitation has been declined.
+ update:
+ error: There was a problem accepting the invitation.
+ success: The invitation has been accepted.
last_activity:
new_proposal: 'New proposal:'
proposal_updated: 'Proposal updated:'
@@ -806,7 +843,7 @@ en:
discard: Discard this draft
discard_confirmation: Are you sure you want to discard this proposal draft?
send: Preview
- title: Edit Proposal Draft
+ title: Edit proposal draft
edit_form_fields:
marker_added: Marker added to the map.
filters:
diff --git a/decidim-proposals/config/locales/es-MX.yml b/decidim-proposals/config/locales/es-MX.yml
index c0f06ac0a0f9b..74b769a0b333a 100644
--- a/decidim-proposals/config/locales/es-MX.yml
+++ b/decidim-proposals/config/locales/es-MX.yml
@@ -170,6 +170,11 @@ es-MX:
random: Aleatorio
recent: Recientes
with_more_authors: Con más autoras
+ edit_time: Las autoras pueden editar las propuestas antes de que pase este tiempo
+ edit_time_units:
+ days: Días
+ hours: Horas
+ minutes: Minutos
geocoding_enabled: Geocodificación habilitada
minimum_votes_per_user: Votos mínimos por usuario
new_proposal_body_template: Plantilla para el texto de nueva propuesta
@@ -179,11 +184,14 @@ es-MX:
participatory_texts_enabled: Textos participativos habilitados
participatory_texts_enabled_readonly: No se puede interactuar con esta configuración si hay propuestas existentes. Por favor, crea un nuevo componente de propuesta si quieres activar esta característica o descartar todas las propuestas importadas en el menú "Textos Participativos" si quieres desactivarla.
proposal_answering_enabled: Respuesta a propuestas habilitadas
- proposal_edit_before_minutes: Las propuestas pueden ser editadas por los autores antes de que pasen estos minutos
proposal_edit_time: Edición de propuestas
proposal_edit_time_choices:
infinite: Permitir editar propuestas por una cantidad infinita de tiempo
limited: Permitir la edición de propuestas dentro de un plazo específico
+ proposal_edit_time_unit_options:
+ days: Días
+ hours: Horas
+ minutes: Minutos
proposal_length: Longitud máxima del cuerpo de la propuesta
proposal_limit: Límite de propuestas por usuario
proposal_wizard_step_1_help_text: Texto de ayuda para el paso "Crear" del asistente de propuesta
@@ -234,11 +242,26 @@ es-MX:
events:
proposals:
admin:
+ proposal_assigned_to_valuator:
+ email_intro: Se te ha asignado como evaluadora de la propuesta "%{resource_title}". Esto significa que se ha confiado en ti para dar tu opinión y dar una respuesta adecuada en los próximos días. Puedes ver la propuesta en el
panel de administración.
+ email_outro: Recibes esta notificación porque puedes evaluar la propuesta.
+ email_subject: Has sido asignada como evaluadora de la propuesta "%{resource_title}".
+ notification_title: Se te ha asignado como evaluadora de la propuesta "
%{resource_title}". Puedes verla en el
panel de administración.
proposal_note_created:
- email_intro: Alguien ha dejado una nota en la propuesta "%{resource_title}". Revísala ahora a través del
panel de administración.
+ email_intro: '%{author_name} ha creado una nota privada en %{resource_title}. Puedes verlo en el
panel de administración.'
email_outro: Recibes esta notificación porque puedes evaluar la propuesta.
email_subject: Alguien dejó una nota en la propuesta %{resource_title}.
- notification_title: Alguien ha dejado una nota en la propuesta
%{resource_title}. Revísala ahora a través del
panel de administración.
+ notification_title:
%{author_name} %{author_nickname} ha creado una nota privada en
%{resource_title}. Puedes verla en el
panel de administración.
+ proposal_note_mentioned:
+ email_intro: '"%{author_name}" "%{author_nickname}" te ha mencionado en una nota privada en "%{resource_title}". Puedes verla en el
panel de administración.'
+ email_outro: Has recibido esta notificación porque se te ha mencionado en una nota privada.
+ email_subject: Alguien dejó una nota en la propuesta %{resource_title}.
+ notification_title:
%{author_name} %{author_nickname} te ha mencionado en una nota privada en
%{resource_title}. Puedes verla en el
panel de administración.
+ proposal_note_replied:
+ email_intro: '%{author_name} ha respondido a tu nota privada en %{resource_title}. Puedes verlo en el
panel de administración.'
+ email_outro: Has recibido esta notificación porque eres el autor de la nota privada.
+ email_subject: "%{author_name} ha respondido a tu nota privada en %{resource_title}."
+ notification_title:
%{author_name} %{author_nickname} ha respondido a tu nota privada en
%{resource_title}. Puedes verlo en el
panel de administración.
collaborative_draft_access_accepted:
email_intro: '%{requester_name} ha sido aceptada para acceder como contribuidora del borrador colaborativo
%{resource_title}.'
email_outro: Has recibido esta notificación porque eres una contribuidora de
%{resource_title}.
@@ -473,7 +496,9 @@ es-MX:
form:
note: Nota
submit: Enviar
- leave_your_note: Deja tu nota
+ reply:
+ error: Se ha producido un error al crear esta respuesta en la nota privada.
+ success: La respuesta a la nota privada se ha creado con éxito.
title: Notas privadas
proposal_states:
create:
diff --git a/decidim-proposals/config/locales/es-PY.yml b/decidim-proposals/config/locales/es-PY.yml
index 0d7b52140d4f8..260098a805e1c 100644
--- a/decidim-proposals/config/locales/es-PY.yml
+++ b/decidim-proposals/config/locales/es-PY.yml
@@ -170,6 +170,11 @@ es-PY:
random: Aleatorio
recent: Recientes
with_more_authors: Con más autoras
+ edit_time: Las autoras pueden editar las propuestas antes de que pase este tiempo
+ edit_time_units:
+ days: Días
+ hours: Horas
+ minutes: Minutos
geocoding_enabled: Geocodificación habilitada
minimum_votes_per_user: Votos mínimos por usuario
new_proposal_body_template: Plantilla para el texto de nueva propuesta
@@ -179,11 +184,14 @@ es-PY:
participatory_texts_enabled: Textos participativos habilitados
participatory_texts_enabled_readonly: No se puede interactuar con esta configuración si hay propuestas existentes. Por favor, crea un nuevo componente de propuesta si quieres activar esta característica o descartar todas las propuestas importadas en el menú "Textos Participativos" si quieres desactivarla.
proposal_answering_enabled: Respuesta a propuestas habilitadas
- proposal_edit_before_minutes: Las propuestas pueden ser editadas por los autores antes de que pasen estos minutos
proposal_edit_time: Edición de propuestas
proposal_edit_time_choices:
infinite: Permitir editar propuestas por una cantidad infinita de tiempo
limited: Permitir la edición de propuestas dentro de un plazo específico
+ proposal_edit_time_unit_options:
+ days: Días
+ hours: Horas
+ minutes: Minutos
proposal_length: Longitud máxima del cuerpo de la propuesta
proposal_limit: Límite de propuestas por usuario
proposal_wizard_step_1_help_text: Asistente de propuesta "Crear" paso texto de ayuda
@@ -234,11 +242,26 @@ es-PY:
events:
proposals:
admin:
+ proposal_assigned_to_valuator:
+ email_intro: Se te ha asignado como evaluadora de la propuesta "%{resource_title}". Esto significa que se ha confiado en ti para dar tu opinión y dar una respuesta adecuada en los próximos días. Puedes ver la propuesta en el
panel de administración.
+ email_outro: Recibes esta notificación porque puedes evaluar la propuesta.
+ email_subject: Has sido asignada como evaluadora de la propuesta "%{resource_title}".
+ notification_title: Se te ha asignado como evaluadora de la propuesta "
%{resource_title}". Puedes verla en el
panel de administración.
proposal_note_created:
- email_intro: Alguien ha dejado una nota en la propuesta "%{resource_title}". Revísala ahora a través del
panel de administración.
+ email_intro: '%{author_name} ha creado una nota privada en %{resource_title}. Puedes verlo en el
panel de administración.'
email_outro: Recibes esta notificación porque puedes evaluar la propuesta.
email_subject: Alguien dejó una nota en la propuesta %{resource_title}.
- notification_title: Alguien ha dejado una nota en la propuesta
%{resource_title}. Revísala ahora a través del
panel de administración.
+ notification_title:
%{author_name} %{author_nickname} ha creado una nota privada en
%{resource_title}. Puedes verla en el
panel de administración.
+ proposal_note_mentioned:
+ email_intro: '"%{author_name}" "%{author_nickname}" te ha mencionado en una nota privada en "%{resource_title}". Puedes verla en el
panel de administración.'
+ email_outro: Has recibido esta notificación porque se te ha mencionado en una nota privada.
+ email_subject: Alguien dejó una nota en la propuesta %{resource_title}.
+ notification_title:
%{author_name} %{author_nickname} te ha mencionado en una nota privada en
%{resource_title}. Puedes verla en el
panel de administración.
+ proposal_note_replied:
+ email_intro: '%{author_name} ha respondido a tu nota privada en %{resource_title}. Puedes verlo en el
panel de administración.'
+ email_outro: Has recibido esta notificación porque eres el autor de la nota privada.
+ email_subject: "%{author_name} ha respondido a tu nota privada en %{resource_title}."
+ notification_title:
%{author_name} %{author_nickname} ha respondido a tu nota privada en
%{resource_title}. Puedes verlo en el
panel de administración.
collaborative_draft_access_accepted:
email_intro: '%{requester_name} ha sido aceptada para acceder como contribuidora del borrador colaborativo
%{resource_title}.'
email_outro: Has recibido esta notificación porque eres una contribuidora de
%{resource_title}.
@@ -473,7 +496,9 @@ es-PY:
form:
note: Nota
submit: Enviar
- leave_your_note: Deja tu nota
+ reply:
+ error: Se ha producido un error al crear esta respuesta en la nota privada.
+ success: La respuesta a la nota privada se ha creado con éxito.
title: Notas privadas
proposal_states:
create:
diff --git a/decidim-proposals/config/locales/es.yml b/decidim-proposals/config/locales/es.yml
index 7639928fbf743..a2aa690cd43f4 100644
--- a/decidim-proposals/config/locales/es.yml
+++ b/decidim-proposals/config/locales/es.yml
@@ -170,6 +170,11 @@ es:
random: Aleatorio
recent: Recientes
with_more_authors: Con más autoras
+ edit_time: Las autoras pueden editar las propuestas antes de que pase este tiempo
+ edit_time_units:
+ days: Días
+ hours: Horas
+ minutes: Minutos
geocoding_enabled: Geocodificación habilitada
minimum_votes_per_user: Votos mínimos por usuario
new_proposal_body_template: Plantilla para el texto de nueva propuesta
@@ -179,11 +184,14 @@ es:
participatory_texts_enabled: Textos participativos habilitados
participatory_texts_enabled_readonly: No se puede interactuar con esta configuración si hay propuestas existentes. Por favor, crea un nuevo componente de propuesta si quieres activar esta característica o descartar todas las propuestas importadas en el menú "Textos Participativos" si quieres desactivarla.
proposal_answering_enabled: Respuesta a propuestas habilitada
- proposal_edit_before_minutes: Las propuestas pueden ser editadas por las autoras antes de que pasen estos minutos
proposal_edit_time: Edición de propuestas
proposal_edit_time_choices:
infinite: Permitir editar propuestas por una cantidad infinita de tiempo
limited: Permitir la edición de propuestas dentro de un plazo específico
+ proposal_edit_time_unit_options:
+ days: Días
+ hours: Horas
+ minutes: Minutos
proposal_length: Longitud máxima del cuerpo de la propuesta
proposal_limit: Límite de propuestas por participante
proposal_wizard_step_1_help_text: Texto de ayuda para el paso "Crear" del asistente de propuestas
@@ -234,11 +242,26 @@ es:
events:
proposals:
admin:
+ proposal_assigned_to_valuator:
+ email_intro: Se te ha asignado como evaluadora de la propuesta "%{resource_title}". Esto significa que se ha confiado en ti para dar tu opinión y dar una respuesta adecuada en los próximos días. Puedes ver la propuesta en el
panel de administración.
+ email_outro: Recibes esta notificación porque puedes evaluar la propuesta.
+ email_subject: Has sido asignada como evaluadora de la propuesta "%{resource_title}".
+ notification_title: Se te ha asignado como evaluadora de la propuesta "
%{resource_title}". Puedes verla en el
panel de administración.
proposal_note_created:
- email_intro: Alguien ha dejado una nota en la propuesta "%{resource_title}". Revísala ahora a través del
panel de administración.
+ email_intro: '%{author_name} ha creado una nota privada en %{resource_title}. Puedes verlo en el
panel de administración.'
email_outro: Recibes esta notificación porque puedes evaluar la propuesta.
email_subject: Alguien dejó una nota en la propuesta %{resource_title}.
- notification_title: Alguien ha dejado una nota en la propuesta
%{resource_title}. Revísala ahora a través del
panel de administración.
+ notification_title:
%{author_name} %{author_nickname} ha creado una nota privada en
%{resource_title}. Puedes verla en el
panel de administración.
+ proposal_note_mentioned:
+ email_intro: '"%{author_name}" "%{author_nickname}" te ha mencionado en una nota privada en "%{resource_title}". Puedes verla en el
panel de administración.'
+ email_outro: Has recibido esta notificación porque se te ha mencionado en una nota privada.
+ email_subject: Alguien dejó una nota en la propuesta %{resource_title}.
+ notification_title:
%{author_name} %{author_nickname} te ha mencionado en una nota privada en
%{resource_title}. Puedes verla en el
panel de administración.
+ proposal_note_replied:
+ email_intro: '%{author_name} ha respondido a tu nota privada en %{resource_title}. Puedes verlo en el
panel de administración.'
+ email_outro: Has recibido esta notificación porque eres el autor de la nota privada.
+ email_subject: "%{author_name} ha respondido a tu nota privada en %{resource_title}."
+ notification_title:
%{author_name} %{author_nickname} ha respondido a tu nota privada en
%{resource_title}. Puedes verlo en el
panel de administración.
collaborative_draft_access_accepted:
email_intro: '%{requester_name} ha sido aceptada para acceder como contribuidora del borrador colaborativo
%{resource_title}.'
email_outro: Has recibido esta notificación porque eres una contribuidora de
%{resource_title}.
@@ -473,7 +496,9 @@ es:
form:
note: Nota
submit: Enviar
- leave_your_note: Deja tu nota
+ reply:
+ error: Se ha producido un error al crear esta respuesta en la nota privada.
+ success: La respuesta a la nota privada se ha creado con éxito.
title: Notas privadas
proposal_states:
create:
diff --git a/decidim-proposals/config/locales/eu.yml b/decidim-proposals/config/locales/eu.yml
index 22a8cc9072434..e2d819124ee5d 100644
--- a/decidim-proposals/config/locales/eu.yml
+++ b/decidim-proposals/config/locales/eu.yml
@@ -176,7 +176,6 @@ eu:
participatory_texts_enabled: Testu parte-hartzaileak gaituta
participatory_texts_enabled_readonly: Proposamenak badaude, ezin da ezarpen honekin elkarreragin. Mesedez, sor ezazu proposamen-osagai berria, ezaugarri hau aktibatu nahi baduzu edo baztertu `Testu parte hartzaileak` menuan inportatutako proposamen guztiak, desaktibatu nahi baduzu.
proposal_answering_enabled: Proposamena erantzutea gaituta dago
- proposal_edit_before_minutes: Proposamenak egileek editatu ahal izango dituzte minutu asko igaro aurretik
proposal_edit_time: Proposamenen edizioa
proposal_edit_time_choices:
infinite: Utzi proposamenak editatzen epe mugagabe batean
@@ -232,10 +231,8 @@ eu:
proposals:
admin:
proposal_note_created:
- email_intro: 'Norbaitek ohar bat utzi du "%{resource_title}" proposamenean. Berrikusimorain hemen:
the admin panel.'
email_outro: Jakinarazpen hau jaso duzu proposamena ebaluatu ahal duzulako.
email_subject: Norbaitek ohar bat utzi du %{resource_title} proposamenean.
- notification_title: Norbaitek ohar bat utzi du
%{resource_title} proposamenean. Berrikusi orain honen bidez
panel de administración.
collaborative_draft_access_accepted:
email_intro: '%{requester_name} onartu da
%{resource_title} zirriborro koloboratiboan laguntzaile gisa sartzeko.'
email_outro: Jakinarazpen hau jaso duzu
%{resource_title}-ko kolaboratzailea zarelako.
@@ -471,7 +468,6 @@ eu:
form:
note: Oharra
submit: Bidali
- leave_your_note: Utzi zure oharra
title: Ohar pribatuak
proposal_states:
create:
diff --git a/decidim-proposals/config/locales/fi-plain.yml b/decidim-proposals/config/locales/fi-plain.yml
index 25e3ef6f2ccc3..6da134609434d 100644
--- a/decidim-proposals/config/locales/fi-plain.yml
+++ b/decidim-proposals/config/locales/fi-plain.yml
@@ -170,6 +170,11 @@ fi-pl:
random: Satunnainen
recent: Viimeisimmät
with_more_authors: Eniten tekijöitä
+ edit_time: Ehdotuksia voi muokata tämän aikamääreen sisällä
+ edit_time_units:
+ days: Päivää
+ hours: Tuntia
+ minutes: Minuuttia
geocoding_enabled: Geokoodaus käytössä
minimum_votes_per_user: Vähimmäisäänimäärä käyttäjää kohden
new_proposal_body_template: Uuden ehdotuksen leipätekstin mallipohja
@@ -179,11 +184,14 @@ fi-pl:
participatory_texts_enabled: Ehdotusaineistot ovat käytössä
participatory_texts_enabled_readonly: Tätä asetusta ei voi muuttaa, mikäli ehdotuksia on jo olemassa. Luo uusi "Ehdotukset-komponentti", mikäli haluat ottaa tämän ominaisuuden käyttöön tai hylkää kaikki tuodut ehdotukset "Ehdotusaineistot" -toiminnosta, mikäli haluat ottaa sen pois käytöstä.
proposal_answering_enabled: Ehdotukseen vastaaminen käytössä
- proposal_edit_before_minutes: Tekijät voivat muokata ehdotuksia tämän ajan sisällä (minuuttia)
proposal_edit_time: Ehdotusten muokkaus
proposal_edit_time_choices:
infinite: Ehdotusten muokkaus on sallittu ilman aikarajaa
limited: Ehdotusten muokkaus on sallittu määritetyn aikarajan sisällä niiden julkaisusta
+ proposal_edit_time_unit_options:
+ days: Päivää
+ hours: Tuntia
+ minutes: Minuuttia
proposal_length: Ehdotuksen runkotekstin merkkien enimmäismäärä
proposal_limit: Ehdotusten enimmäismäärä käyttäjää kohden
proposal_wizard_step_1_help_text: Ehdotuksen luonnin "Luo" -vaiheen ohjeteksti
@@ -234,11 +242,26 @@ fi-pl:
events:
proposals:
admin:
+ proposal_assigned_to_valuator:
+ email_intro: Sinulle on annettu arvioitavaksi ehdotus "%{resource_title}". Tämä tarkoittaa, että sinut on valtuutettu antamaan palautetta ja vastaamaan ehdotukseen tulevien päivien aikana. Tarkasta ehdotus
hallintapaneelin kautta.
+ email_outro: Tämä ilmoitus on lähetetty sinulle, koska voit arvioida ehdotuksen.
+ email_subject: Sinulle on annettu arvioitavaksi ehdotus %{resource_title}.
+ notification_title: Sinulle on annettu arvioitavaksi ehdotus
"%{resource_title}". Tarkasta ehdotus
hallintapaneelin kautta.
proposal_note_created:
- email_intro: Joku on jättänyt muistiinpanon ehdotukseen "%{resource_title}". Tutustu siihen
hallintapaneelin kautta.
+ email_intro: '%{author_name} on luonut yksityisen muistiinpanon kohteeseen %{resource_title}. Tarkasta muistiinpano
hallintapaneelin kautta.'
email_outro: Saat tämän ilmoituksen, koska voit arvioida ehdotuksen.
email_subject: Joku on jättänyt huomion ehdotukseen %{resource_title}.
- notification_title: Joku on jättänyt muistiinpanon ehdotukseen
%{resource_title}. Tutustu siihen
hallintapaneelin kautta.
+ notification_title:
%{author_name} on luonut yksityisen muistiinpanon kohteeseen
%{resource_title}. Tarkasta muistiinpano
hallintapaneelin kautta.
+ proposal_note_mentioned:
+ email_intro: Sinut on mainittu yksityisessä muistiinpanossa "%{resource_title}" henkilön "%{author_name}" "%{author_nickname}" toimesta. Tarkista muistiinpano
hallintapaneelin kautta.
+ email_outro: Tämä ilmoitus on lähetetty sinulle, koska sinut on mainittu yksityisessä muistiinpanossa.
+ email_subject: Sinut on mainittu ehdotuksen %{resource_title} muistiinpanossa.
+ notification_title: Sinut on mainittu yksityisessä muistiinpanossa
%{resource_title} henkilön
%{author_name} %{author_nickname} toimesta. Tarkista se
hallintapaneelin kautta.
+ proposal_note_replied:
+ email_intro: '%{author_name} on vastannut yksityiseen muistiinpanoon kohteessa %{resource_title}. Tarkasta muistiinpano
hallintapaneelin kautta.'
+ email_outro: Sait tämän ilmoituksen, koska olet muistiinpanon laatija.
+ email_subject: "%{author_name} on vastannut yksityiseen muistiinpanoon kohteessa %{resource_title}."
+ notification_title:
%{author_name}%{author_nickname} on vastannut yksityiseen muistiinpanoosi kohteessa
%{resource_title}. Tarkasta muistiinpano
hallintapaneelin kautta.
collaborative_draft_access_accepted:
email_intro: '%{requester_name} on hyväksytty osallistujaksi yhteistyöluonnokseen
%{resource_title}.'
email_outro: Tämä ilmoitus on lähetetty sinulle, koska olet osallistujana kohteessa
%{resource_title}.
@@ -472,7 +495,9 @@ fi-pl:
form:
note: Huomautus
submit: Lähetä
- leave_your_note: Jätä huomautuksesi
+ reply:
+ error: Muistiinpanon vastauksen luonti ehdotukselle epäonnistui.
+ success: Muistiinpanon vastauksen luonti ehdotukselle onnistui.
title: Omat muistiinpanot
proposal_states:
create:
diff --git a/decidim-proposals/config/locales/fi.yml b/decidim-proposals/config/locales/fi.yml
index f689417e56e0b..98d39038bd0ea 100644
--- a/decidim-proposals/config/locales/fi.yml
+++ b/decidim-proposals/config/locales/fi.yml
@@ -170,6 +170,11 @@ fi:
random: Satunnainen
recent: Viimeisimmät
with_more_authors: Eniten tekijöitä
+ edit_time: Ehdotuksia voi muokata tämän aikamääreen sisällä
+ edit_time_units:
+ days: Päivää
+ hours: Tuntia
+ minutes: Minuuttia
geocoding_enabled: Geokoodaus käytössä
minimum_votes_per_user: Vähimmäisäänimäärä käyttäjää kohden
new_proposal_body_template: Uuden ehdotuksen leipätekstin mallipohja
@@ -179,11 +184,14 @@ fi:
participatory_texts_enabled: Ehdotusaineistot ovat käytössä
participatory_texts_enabled_readonly: Tätä asetusta ei voi muuttaa, mikäli ehdotuksia on jo olemassa. Luo uusi "Ehdotukset-komponentti", mikäli haluat ottaa tämän ominaisuuden käyttöön tai hylkää kaikki tuodut ehdotukset "Ehdotusaineistot" -toiminnosta, mikäli haluat ottaa sen pois käytöstä.
proposal_answering_enabled: Ehdotukseen vastaaminen käytössä
- proposal_edit_before_minutes: Tekijät voivat muokata ehdotuksia tämän ajan sisällä (minuuttia)
proposal_edit_time: Ehdotusten muokkaus
proposal_edit_time_choices:
infinite: Ehdotusten muokkaus on sallittu ilman aikarajaa
limited: Ehdotusten muokkaus on sallittu määritetyn aikarajan sisällä niiden julkaisusta
+ proposal_edit_time_unit_options:
+ days: Päivää
+ hours: Tuntia
+ minutes: Minuuttia
proposal_length: Ehdotuksen runkotekstin merkkien enimmäismäärä
proposal_limit: Ehdotusten enimmäismäärä käyttäjää kohden
proposal_wizard_step_1_help_text: Ehdotuksen luonnin "Luo" -vaiheen ohjeteksti
@@ -234,11 +242,26 @@ fi:
events:
proposals:
admin:
+ proposal_assigned_to_valuator:
+ email_intro: Sinulle on annettu arvioitavaksi ehdotus "%{resource_title}". Tämä tarkoittaa, että sinut on valtuutettu antamaan palautetta ja vastaamaan ehdotukseen tulevien päivien aikana. Tarkasta ehdotus
hallintapaneelin kautta.
+ email_outro: Tämä ilmoitus on lähetetty sinulle, koska voit arvioida ehdotuksen.
+ email_subject: Sinulle on annettu arvioitavaksi ehdotus %{resource_title}.
+ notification_title: Sinulle on annettu arvioitavaksi ehdotus
"%{resource_title}". Tarkasta ehdotus
hallintapaneelin kautta.
proposal_note_created:
- email_intro: Joku on jättänyt muistiinpanon ehdotukseen "%{resource_title}". Tutustu siihen
hallintapaneelin kautta.
+ email_intro: '%{author_name} on luonut yksityisen muistiinpanon kohteeseen %{resource_title}. Tarkasta muistiinpano
hallintapaneelin kautta.'
email_outro: Tämä ilmoitus on lähetetty sinulle, koska voit arvioida ehdotuksen.
email_subject: Joku on jättänyt huomion ehdotukseen %{resource_title}.
- notification_title: Joku on jättänyt muistiinpanon ehdotukseen
%{resource_title}. Tutustu siihen
hallintapaneelin kautta.
+ notification_title:
%{author_name} on luonut yksityisen muistiinpanon kohteeseen
%{resource_title}. Tarkasta muistiinpano
hallintapaneelin kautta.
+ proposal_note_mentioned:
+ email_intro: Sinut on mainittu yksityisessä muistiinpanossa "%{resource_title}" henkilön "%{author_name}" "%{author_nickname}" toimesta. Tarkista muistiinpano
hallintapaneelin kautta.
+ email_outro: Tämä ilmoitus on lähetetty sinulle, koska sinut on mainittu yksityisessä muistiinpanossa.
+ email_subject: Sinut on mainittu ehdotuksen %{resource_title} muistiinpanossa.
+ notification_title: Sinut on mainittu yksityisessä muistiinpanossa
%{resource_title} henkilön
%{author_name} %{author_nickname} toimesta. Tarkista se
hallintapaneelin kautta.
+ proposal_note_replied:
+ email_intro: '%{author_name} on vastannut yksityiseen muistiinpanoon kohteessa %{resource_title}. Tarkasta muistiinpano
hallintapaneelin kautta.'
+ email_outro: Sait tämän ilmoituksen, koska olet muistiinpanon laatija.
+ email_subject: "%{author_name} on vastannut yksityiseen muistiinpanoon kohteessa %{resource_title}."
+ notification_title:
%{author_name}%{author_nickname} on vastannut yksityiseen muistiinpanoosi kohteessa
%{resource_title}. Tarkasta muistiinpano
hallintapaneelin kautta.
collaborative_draft_access_accepted:
email_intro: '%{requester_name} on hyväksytty osallistujaksi yhteistyöluonnokseen
%{resource_title}.'
email_outro: Tämä ilmoitus on lähetetty sinulle, koska olet osallistujana kohteessa
%{resource_title}.
@@ -472,7 +495,9 @@ fi:
form:
note: Huomautus
submit: Lähetä
- leave_your_note: Jätä huomautuksesi
+ reply:
+ error: Muistiinpanon vastauksen luonti ehdotukselle epäonnistui.
+ success: Muistiinpanon vastauksen luonti ehdotukselle onnistui.
title: Omat muistiinpanot
proposal_states:
create:
diff --git a/decidim-proposals/config/locales/fr-CA.yml b/decidim-proposals/config/locales/fr-CA.yml
index dc7989f567516..45e2ba3caec25 100644
--- a/decidim-proposals/config/locales/fr-CA.yml
+++ b/decidim-proposals/config/locales/fr-CA.yml
@@ -179,7 +179,6 @@ fr-CA:
participatory_texts_enabled: Textes participatifs activés
participatory_texts_enabled_readonly: Impossible d'interagir avec ce paramètre s'il y a des propositions existantes. Veuillez créer une nouvelle fonctionnalité `Propositions` si vous voulez activer cette fonctionnalité ou supprimer toutes les propositions importées dans 'Textes participatifs` si vous voulez la désactiver.
proposal_answering_enabled: Autoriser la réponse officielle aux propositions
- proposal_edit_before_minutes: Délai (en minutes) après lequel les auteurs ne peuvent plus modifier leurs propositions
proposal_edit_time: Durée d'édition des propositions
proposal_edit_time_choices:
infinite: Autoriser l'édition des propositions pour une durée infinie
@@ -234,11 +233,13 @@ fr-CA:
events:
proposals:
admin:
+ proposal_assigned_to_valuator:
+ email_outro: Vous avez reçu cette notification car vous pouvez évaluer la proposition.
+ email_subject: Vous avez été assigné en tant qu'évaluateur à la proposition %{resource_title}.
+ notification_title: Vous avez été assigné en tant qu'évaluateur à la proposition
%{resource_title}. Jetez-y un œil sur
le panneau d'administration.
proposal_note_created:
- email_intro: Quelqu'un a laissé une note sur la proposition "%{resource_title}". Consultez-la sur
le panneau d'administration.
email_outro: Vous avez reçu cette notification car vous pouvez évaluer la proposition.
email_subject: Quelqu'un a laissé une note sur la proposition %{resource_title}.
- notification_title: Quelqu'un a laissé une note sur la proposition
%{resource_title}. Consultez-la sur
le panneau d'administration.
collaborative_draft_access_accepted:
email_intro: '%{requester_name} a été accepté en tant que contributeur du brouillon collaboratif
%{resource_title}.'
email_outro: Vous avez reçu cette notification car vous êtes collaborateur de
%{resource_title}. Si vous souhaitez vous désabonner des notifications, connectez-vous à la plateforme, puis rendez-vous dans l'onglet “Mon compte” > “Paramètres des notifications”.
@@ -473,7 +474,6 @@ fr-CA:
form:
note: Remarque
submit: Soumettre
- leave_your_note: Laisser une remarque
title: Notes privées
proposal_states:
create:
diff --git a/decidim-proposals/config/locales/fr.yml b/decidim-proposals/config/locales/fr.yml
index 9ece416ec9bf2..d94ee7e43aac9 100644
--- a/decidim-proposals/config/locales/fr.yml
+++ b/decidim-proposals/config/locales/fr.yml
@@ -179,7 +179,6 @@ fr:
participatory_texts_enabled: Textes participatifs activés
participatory_texts_enabled_readonly: Impossible d'interagir avec ce paramètre s'il y a des propositions existantes. Veuillez créer une nouvelle fonctionnalité `Propositions` si vous voulez activer cette fonctionnalité ou supprimer toutes les propositions importées dans 'Textes participatifs` si vous voulez la désactiver.
proposal_answering_enabled: Autoriser la réponse officielle aux propositions
- proposal_edit_before_minutes: Délai (en minutes) après lequel les auteurs ne peuvent plus modifier leurs propositions
proposal_edit_time: Durée d'édition des propositions
proposal_edit_time_choices:
infinite: Autoriser l'édition des propositions pour une durée infinie
@@ -234,11 +233,13 @@ fr:
events:
proposals:
admin:
+ proposal_assigned_to_valuator:
+ email_outro: Vous avez reçu cette notification car vous pouvez évaluer la proposition.
+ email_subject: Vous avez été assigné en tant qu'évaluateur à la proposition %{resource_title}.
+ notification_title: Vous avez été assigné en tant qu'évaluateur à la proposition
%{resource_title}. Jetez-y un œil sur
le panneau d'administration.
proposal_note_created:
- email_intro: Quelqu'un a laissé une note sur la proposition "%{resource_title}". Consultez-la sur
le panneau d'administration.
email_outro: Vous avez reçu cette notification car vous pouvez évaluer la proposition. Si vous souhaitez vous désabonner des notifications, connectez-vous à la plateforme, puis rendez-vous dans l'onglet “Mon compte” > “Paramètres des notifications”.
email_subject: Quelqu'un a laissé une note sur la proposition %{resource_title}.
- notification_title: Quelqu'un a laissé une note sur la proposition
%{resource_title}. Consultez-la sur
le panneau d'administration.
collaborative_draft_access_accepted:
email_intro: '%{requester_name} a été accepté en tant que contributeur du brouillon collaboratif
%{resource_title}.'
email_outro: Vous avez reçu cette notification car vous êtes collaborateur de
%{resource_title}. Si vous souhaitez vous désabonner des notifications, connectez-vous à la plateforme, puis rendez-vous dans l'onglet “Mon compte” > “Paramètres des notifications”.
@@ -473,7 +474,6 @@ fr:
form:
note: Remarque
submit: Soumettre
- leave_your_note: Laisser une remarque
title: Notes privées
proposal_states:
create:
diff --git a/decidim-proposals/config/locales/gl.yml b/decidim-proposals/config/locales/gl.yml
index a949fcfdb59a9..505c6a2ebaac4 100644
--- a/decidim-proposals/config/locales/gl.yml
+++ b/decidim-proposals/config/locales/gl.yml
@@ -131,7 +131,6 @@ gl:
official_proposals_enabled: Propostas oficiais habilitadas
participatory_texts_enabled: Permitir textos participativos
proposal_answering_enabled: Contestando a proposta habilitada
- proposal_edit_before_minutes: As propostas poden ser editadas por autores antes de que pase moitos minutos
proposal_length: Lonxitude máxima do corpo da proposta
proposal_limit: Límite de proposta por usuario
proposal_wizard_step_1_help_text: Asistente de propostas "Crear" texto de axuda paso a paso
@@ -315,7 +314,6 @@ gl:
form:
note: Nota
submit: Enviar
- leave_your_note: Deixe a súa nota
title: Notas privadas
proposals:
edit:
diff --git a/decidim-proposals/config/locales/hu.yml b/decidim-proposals/config/locales/hu.yml
index 9f99873576b62..31ed0be41031f 100644
--- a/decidim-proposals/config/locales/hu.yml
+++ b/decidim-proposals/config/locales/hu.yml
@@ -132,7 +132,6 @@ hu:
participatory_texts_enabled: Engedélyezett részvételi szövegek
participatory_texts_enabled_readonly: Meglévő javaslatok esetén nem lehet alkalmazni ezt a beállítást. Legyen szíves, egy új 'Javaslatok komponens' -t hozzon létre, hogy ezt a funkciót használja, vagy vesse el az importált javaslatokat a "Részvételi Szövegek" menüben, ha ki akarja kapcsolni.
proposal_answering_enabled: Javaslat válasz engedélyezve
- proposal_edit_before_minutes: A javaslatokat a szerzők az ülés lezárásáig szerkeszthetik
proposal_edit_time: Javaslat szerkesztése
proposal_edit_time_choices:
infinite: A javaslatok szerkesztésének ne legyen időbeli korlátja
@@ -176,10 +175,8 @@ hu:
proposals:
admin:
proposal_note_created:
- email_intro: Valaki egy jegyzetet írt a(z) "%{resource_title}" javaslathoz. Ellenőrizze
az adminisztrációs panelen.
email_outro: Azért kapta ezt az értesítést, mert értékelheti a javaslatot.
email_subject: Valaki egy jegyzetet írt a(z) "%{resource_title}" javaslathoz.
- notification_title: Valaki egy jegyzetet írt a(z)
%{resource_title} javaslathoz. Ellenőrizze
az adminisztrációs panelen.
collaborative_draft_access_accepted:
email_subject: "%{requester_name} jóváhagyva, mint közreműködő ebben: %{resource_title}."
notification_title: '
%{requester_name} %{requester_nickname} jóváhagyva,
mint a közreműködő ebben a közös vázlatban:
%{resource_title}.'
@@ -362,7 +359,6 @@ hu:
form:
note: Jegyzet
submit: Küldés
- leave_your_note: Jegyzet elhagyása
title: Privát jegyzetek
proposal_states:
create:
diff --git a/decidim-proposals/config/locales/id-ID.yml b/decidim-proposals/config/locales/id-ID.yml
index c337d3e51425a..d62ef3226b130 100644
--- a/decidim-proposals/config/locales/id-ID.yml
+++ b/decidim-proposals/config/locales/id-ID.yml
@@ -76,7 +76,6 @@ id:
official_proposals_enabled: Proposal resmi diaktifkan
participatory_texts_enabled: Teks partisipatif diaktifkan
proposal_answering_enabled: Pengangkatan proposal diaktifkan
- proposal_edit_before_minutes: Proposal dapat diedit oleh penulis sebelum ini banyak menit berlalu
proposal_length: Panjang badan proposal maksimum
proposal_limit: Batas proposal per pengguna
proposal_wizard_step_1_help_text: Panduan proposal "Buat" teks bantuan langkah
@@ -233,7 +232,6 @@ id:
form:
note: Catatan
submit: Menyerahkan
- leave_your_note: Tinggalkan catatanmu
title: Catatan pribadi
proposals:
edit:
diff --git a/decidim-proposals/config/locales/is-IS.yml b/decidim-proposals/config/locales/is-IS.yml
index 0486e39d7ad06..983aa16eb0297 100644
--- a/decidim-proposals/config/locales/is-IS.yml
+++ b/decidim-proposals/config/locales/is-IS.yml
@@ -31,7 +31,6 @@ is-IS:
new_proposal_help_text: Ný tillaga hjálpartexta
official_proposals_enabled: Opinberar tillögur virkar
proposal_answering_enabled: Tillaga svarað virkt
- proposal_edit_before_minutes: Tillögur má breyta af höfundum áður en þessi mörg mínútur fara fram
proposal_length: Hámark umsóknar lengd líkamans
proposal_wizard_step_1_help_text: Tillaga töframaður "Búa til" skref hjálpartexta
threshold_per_proposal: Gildi fyrir hverja tillögu
@@ -87,7 +86,6 @@ is-IS:
form:
note: Athugaðu
submit: Senda inn
- leave_your_note: Skildu athugasemdina þína
title: Einkaskilaboð
proposals:
form:
diff --git a/decidim-proposals/config/locales/it.yml b/decidim-proposals/config/locales/it.yml
index bbae6bef5fc01..303b006b1cad2 100644
--- a/decidim-proposals/config/locales/it.yml
+++ b/decidim-proposals/config/locales/it.yml
@@ -136,7 +136,6 @@ it:
participatory_texts_enabled: Testi di partecipazione abilitati
participatory_texts_enabled_readonly: Non è possibile interagire con questa impostazione se ci sono proposte esistenti. Per favore, crea un nuovo componente `Proposte` se si desidera abilitare questa funzione o elimina tutte le proposte importate nel menu `Testi partecipativi` se si desidera disabilitarla.
proposal_answering_enabled: Risposta alla proposta abilitata
- proposal_edit_before_minutes: Minuti dall'inserimento dopo i quali le proposte non potranno piùessere modificate dagli autori
proposal_edit_time: Modifica proposta
proposal_edit_time_choices:
infinite: Consenti la modifica delle proposte per un tempo infinito
@@ -328,7 +327,6 @@ it:
form:
note: Nota
submit: Invia
- leave_your_note: Lascia il tuo messaggio
title: Note private
proposals:
edit:
diff --git a/decidim-proposals/config/locales/ja.yml b/decidim-proposals/config/locales/ja.yml
index b0c3088857f4f..4e4c0a8779a55 100644
--- a/decidim-proposals/config/locales/ja.yml
+++ b/decidim-proposals/config/locales/ja.yml
@@ -175,7 +175,6 @@ ja:
participatory_texts_enabled: 参加型テキストを有効にする
participatory_texts_enabled_readonly: 既存の提案がある場合は、この設定は操作できません。 この機能を有効にする場合は、新しい `提案 コンポーネント` を作成し、もし無効にしたい場合はインポートされたすべての提案を `参加型 テキスト` メニューから破棄してください。
proposal_answering_enabled: 提案への回答を有効にする
- proposal_edit_before_minutes: 作成者が提案を作成してから編集が可能な時間(分)
proposal_edit_time: 提案の編集
proposal_edit_time_choices:
infinite: いつでも提案を編集することを許可する
@@ -231,10 +230,14 @@ ja:
proposals:
admin:
proposal_note_created:
- email_intro: 誰かが提案 "%{resource_title}" にメモを残しました。
管理者パネルで確認してください。
+ email_intro: '%{author_name} は %{resource_title} でプライベートノートを作成しました。
管理パネル で確認してください。'
email_outro: 提案を評価できるため、この通知を受け取りました。
email_subject: 誰かが提案 %{resource_title} にメモを残しました。
- notification_title: 誰かが提案
%{resource_title} にメモを残しました。詳細は
管理者パネルで確認してください。
+ notification_title:
%{author_name} %{author_nickname} が
%{resource_title}にプライベートノートを作成しました。
管理者パネル で確認してください。
+ proposal_note_mentioned:
+ email_intro: '"%{resource_title}" 内の "%{author_name}" "%{author_nickname}" によるプライベートノートで言及されました。
管理パネルで確認してください。'
+ email_outro: プライベートノートで言及されているため、この通知を受信しました。
+ email_subject: 誰かが提案 %{resource_title} のメモであなたをメンションしました。
collaborative_draft_access_accepted:
email_intro: '%{requester_name} は、
%{resource_title} の共同草案のコントリビューターとして承認されました。'
email_outro:
%{resource_title} のコラボレーターであるため、この通知を受け取りました。
@@ -467,7 +470,6 @@ ja:
form:
note: メモ
submit: 送信
- leave_your_note: メモを残してください
title: プライベートノート
proposal_states:
create:
diff --git a/decidim-proposals/config/locales/lt.yml b/decidim-proposals/config/locales/lt.yml
index 9a71bb3dd73dc..0561484ec5d1d 100644
--- a/decidim-proposals/config/locales/lt.yml
+++ b/decidim-proposals/config/locales/lt.yml
@@ -158,7 +158,6 @@ lt:
participatory_texts_enabled: Dalyvaujamieji tekstai aktyvuoti
participatory_texts_enabled_readonly: Jei yra pasiūlymų, negalima sąveika su šia nuostata. Sukurkite naują „Pasiūlymų komponentą“, jei norite aktyvinti šią funkciją arba, jei norite išjungti šią funkciją, visus importuotus pasiūlymus pašalinkite iš laukelio „Bendri tekstai“ meniu.
proposal_answering_enabled: Atsakymas į pasiūlymą aktyvintas
- proposal_edit_before_minutes: Kol nepraeis nurodytas skaičius minučių, autoriai gali keisti pasiūlymus
proposal_edit_time: Pasiūlymų koregavimas
proposal_edit_time_choices:
infinite: Lesti redaguoti pasiūlymus neribotą laiką
@@ -206,10 +205,8 @@ lt:
proposals:
admin:
proposal_note_created:
- email_intro: Kažkas paliko pastabą dėl pasiūlymo „%{resource_title}“. Pasitikrinkite tai
administratoriaus srityje.
email_outro: Šį pranešimą gavote dėl to, kad galite vertinti pasiūlymą.
email_subject: Kažkas paliko pastabą dėl pasiūlymo „%{resource_title}“.
- notification_title: Kažkas paliko pastabą dėl pasiūlymo
%{resource_title}. Peržiūrėkite ją
administratoriaus srityje.
collaborative_draft_access_accepted:
email_intro: '%{requester_name} buvo priimtas kaip
%{resource_title} bendradarbiavimo juodraščio bendradarbis.'
email_outro: Šį pranešimą gavote dėl to, kad esate
%{resource_title} bendraautorius.
@@ -416,7 +413,6 @@ lt:
form:
note: Pastaba
submit: Pateikti
- leave_your_note: Palikite pastabą
title: Privačios pastabos
proposals:
answer:
diff --git a/decidim-proposals/config/locales/lv.yml b/decidim-proposals/config/locales/lv.yml
index 96c2864870979..540d570a307b0 100644
--- a/decidim-proposals/config/locales/lv.yml
+++ b/decidim-proposals/config/locales/lv.yml
@@ -101,7 +101,6 @@ lv:
participatory_texts_enabled: Līdzdalības teksti ir iespējoti
participatory_texts_enabled_readonly: Nevar mijiedarboties ar šo iestatījumu, ja jau ir priekšlikumi. Lūdzu, izveidojiet priekšlikumu komponentu, ja vēlaties iespējot šo funkciju, vai atmetiet visus importētos priekšlikumus izvēlnē „Līdzdalības teksti”, ja vēlaties to atspējot.
proposal_answering_enabled: Atbilde uz priekšlikumiem ir iespējota
- proposal_edit_before_minutes: Autori var rediģēt priekšlikumus, pirms ir pagājušas tik daudz minūtes
proposal_length: Maksimālais priekšlikuma pamatteksta garums
proposal_limit: Priekšlikumu skaita limits vienam dalībniekam
proposal_wizard_step_1_help_text: Priekšlikumu vedņa „Izveidot” soļa palīdzības teksts
@@ -277,7 +276,6 @@ lv:
form:
note: Piezīme
submit: Iesniegt
- leave_your_note: Atstājiet savu piezīmi
title: Privātas piezīmes
proposals:
edit:
diff --git a/decidim-proposals/config/locales/nl.yml b/decidim-proposals/config/locales/nl.yml
index 39c38798acccf..3b229d1eebc34 100644
--- a/decidim-proposals/config/locales/nl.yml
+++ b/decidim-proposals/config/locales/nl.yml
@@ -124,7 +124,6 @@ nl:
participatory_texts_enabled: Participatieve teksten ingeschakeld
participatory_texts_enabled_readonly: Instelling niet aanpasbaar als er bestaande voorstellen zijn. Maak een nieuwe `Voorstellen component` aan als u deze functie wilt inschakelen of wijs alle geïmporteerde voorstellen in het `Participatieve Teksten` menu af, als u de instelling wilt uitschakelen.
proposal_answering_enabled: Reacties op voorstellen ingeschakeld
- proposal_edit_before_minutes: Voorstellen kunnen door auteurs worden bewerkt voordat de tijd (uitgedrukt in minuten) verstreken is
proposal_edit_time: Voorstel bewerken
proposal_edit_time_choices:
infinite: Voorstellen onbeperkt in tijd laten bewerken
@@ -337,7 +336,6 @@ nl:
form:
note: Opmerking
submit: Bevestigen
- leave_your_note: Laat je opmerking achter
title: Privé-opmerkingen
proposals:
edit:
diff --git a/decidim-proposals/config/locales/no.yml b/decidim-proposals/config/locales/no.yml
index 0865c4170b2e4..e92d67a9dfe4f 100644
--- a/decidim-proposals/config/locales/no.yml
+++ b/decidim-proposals/config/locales/no.yml
@@ -136,7 +136,6 @@
participatory_texts_enabled: Deltakende tekster aktivert
participatory_texts_enabled_readonly: Kan ikke samhandle med denne innstillingen hvis det finnes eksisterende forslag. Vennligst, opprett et nytt "Forslags komponent" hvis du vil aktivere denne funksjonen eller forkaste alle importerte forslag i `Deltakende tekster` -menyen hvis du vil deaktivere den.
proposal_answering_enabled: Forslags besvaring aktivert
- proposal_edit_before_minutes: Forslag kan redigeres av forfattere før så mange minutter går
proposal_edit_time: Forslagsredigering
proposal_edit_time_choices:
infinite: Tillat å redigere forslag til en uendelig tidsperiode
@@ -337,7 +336,6 @@
form:
note: Merk
submit: Send inn
- leave_your_note: Legg igjen notatene dine
title: Private notater
proposals:
edit:
diff --git a/decidim-proposals/config/locales/pl.yml b/decidim-proposals/config/locales/pl.yml
index 4591ba36bd731..8e17b356ed216 100644
--- a/decidim-proposals/config/locales/pl.yml
+++ b/decidim-proposals/config/locales/pl.yml
@@ -182,7 +182,6 @@ pl:
participatory_texts_enabled: Włącz kolektywną legislację
participatory_texts_enabled_readonly: Nie można korzystać z tego ustawienia, jeśli są już propozycje. Utwórz nowy komponent propozycji, jeśli chcesz włączyć tę funkcję, lub odrzuć wszystkie zaimportowane propozycje w menu „Kolektywna Legislacja”, jeśli chcesz ją wyłączyć.
proposal_answering_enabled: Włączono odpowiadanie na propozycję
- proposal_edit_before_minutes: Propozycje mogą być edytowane przez autorów przed upływem tylu minut
proposal_edit_time: Edycja propozycji
proposal_edit_time_choices:
infinite: Zezwalaj na edycję propozycji przez nieograniczony czas
@@ -238,10 +237,8 @@ pl:
proposals:
admin:
proposal_note_created:
- email_intro: Ktoś zostawił notatkę do propozycji „%{resource_title}”. Sprawdź ją w
panelu administratora.
email_outro: Otrzymujesz to powiadomienie, ponieważ możesz weryfikować propozycję.
email_subject: Ktoś zostawił notatkę do propozycji %{resource_title}.
- notification_title: Ktoś zostawił notatkę do propozycji
%{resource_title}. Sprawdź ją w
panelu administratora.
collaborative_draft_access_accepted:
email_intro: '%{requester_name} otrzymał(a) dostęp jako współtwórca wspólnego szkicu
%{resource_title}.'
email_outro: Otrzymujesz to powiadomienie, ponieważ współpracujesz przy dokumencie
%{resource_title}.
@@ -475,7 +472,6 @@ pl:
form:
note: Notatka
submit: Zatwierdź
- leave_your_note: Zostaw swoją notatkę
title: Prywatne notatki
proposal_states:
create:
diff --git a/decidim-proposals/config/locales/pt-BR.yml b/decidim-proposals/config/locales/pt-BR.yml
index 3dd0e1f116759..57363c26c8cda 100644
--- a/decidim-proposals/config/locales/pt-BR.yml
+++ b/decidim-proposals/config/locales/pt-BR.yml
@@ -140,7 +140,6 @@ pt-BR:
participatory_texts_enabled: Textos participativos habilitados
participatory_texts_enabled_readonly: Não é possível interagir com esta configuração se houver propostas existentes. Por Favor, crie um novo componente `Propostas` se você quiser habilitar esta funcionalidade ou descartar todas as propostas importadas no menu `Textos Participatórios` se você quiser desativá-la.
proposal_answering_enabled: Resposta de proposta ativada
- proposal_edit_before_minutes: As propostas podem ser editadas pelos autores antes que muitos minutos passem.
proposal_edit_time: Editando proposta
proposal_edit_time_choices:
infinite: Permitir a edição de propostas por um período infinito de tempo
@@ -381,7 +380,6 @@ pt-BR:
form:
note: Nota
submit: Enviar
- leave_your_note: Deixe sua nota
title: Notas privadas
proposals:
edit:
diff --git a/decidim-proposals/config/locales/pt.yml b/decidim-proposals/config/locales/pt.yml
index 36ef3f4f77c63..7a89107bb51e2 100644
--- a/decidim-proposals/config/locales/pt.yml
+++ b/decidim-proposals/config/locales/pt.yml
@@ -141,7 +141,6 @@ pt:
participatory_texts_enabled: Textos participativos ativados
participatory_texts_enabled_readonly: Não é possível interagir com esta configuração caso existam propostas. Crie um novo "Componente de propostas" caso pretenda ativar esta característica ou elimine todas as propostas importadas no menu "Textos Participativos" caso pretenda desativá-la.
proposal_answering_enabled: Respostas à proposta ativadas
- proposal_edit_before_minutes: As propostas podem ser editadas pelos autores antes que estes minutos passem
proposal_edit_time: Edição de proposta
proposal_edit_time_choices:
infinite: Permitir editar propostas por um limite de tempo indeterminado
@@ -340,7 +339,6 @@ pt:
form:
note: Nota
submit: Submeter
- leave_your_note: Deixe a sua nota
title: Notas privadas
proposals:
edit:
diff --git a/decidim-proposals/config/locales/ro-RO.yml b/decidim-proposals/config/locales/ro-RO.yml
index cb644d9a4ef83..a5c232252b104 100644
--- a/decidim-proposals/config/locales/ro-RO.yml
+++ b/decidim-proposals/config/locales/ro-RO.yml
@@ -144,7 +144,6 @@ ro:
participatory_texts_enabled: Modulul texte participative a fost activat
participatory_texts_enabled_readonly: Nu se poate interacționa cu această setare dacă există deja propuneri. Te rugăm, creează o nouă componenta 'Propuneri' dacă dorești să activezi această funcționalitate. Dacă vrei să o dezactivezi mergi în meniul `Texte participative`și renunță la toate propunerile importate.
proposal_answering_enabled: Modulul de răspuns pentru propuneri a fost activat
- proposal_edit_before_minutes: Propunerile pot fi editate de către autori până la expirarea termenului definit mai jos în minute
proposal_edit_time: Durata editării propunerii
proposal_edit_time_choices:
infinite: Permite editarea propunerilor pentru o perioadă infinită de timp
@@ -356,7 +355,6 @@ ro:
form:
note: Notă
submit: Trimite
- leave_your_note: Lasă-ți nota
title: Note private
proposals:
edit:
diff --git a/decidim-proposals/config/locales/ru.yml b/decidim-proposals/config/locales/ru.yml
index c71d795a6204c..5ee1458778bc1 100644
--- a/decidim-proposals/config/locales/ru.yml
+++ b/decidim-proposals/config/locales/ru.yml
@@ -65,7 +65,6 @@ ru:
new_proposal_help_text: Подсказки по созданию нового предложения
official_proposals_enabled: Включена возможность выдвигать служебные предложения
proposal_answering_enabled: Включена возможность отвечать на предложения
- proposal_edit_before_minutes: Предложения могут быть отредактированы авторами до того, как пройдет столько минут
proposal_length: Предельная длина основного текста предложения
proposal_limit: Предельное количество предложений от одного участника
proposal_wizard_step_1_help_text: Справка мастера предложений о шаге "Создать"
@@ -131,7 +130,6 @@ ru:
form:
note: Примечание
submit: Отправить
- leave_your_note: Оставьте свое примечание
title: Частные примечания
proposals:
form:
diff --git a/decidim-proposals/config/locales/sk.yml b/decidim-proposals/config/locales/sk.yml
index c9fdf4d93516c..ae46a642f6e9a 100644
--- a/decidim-proposals/config/locales/sk.yml
+++ b/decidim-proposals/config/locales/sk.yml
@@ -107,7 +107,6 @@ sk:
participatory_texts_enabled: Povolené participatívne texty
participatory_texts_enabled_readonly: Ak existujú návrhy, nemožno toto nastavenie meniť. Prosíme vytvorte novú "Súčasť návrhov", ak ho chcete povoliť, alebo zahoďte všetky importované návrhy v "Participatívnych textoch" v menu, ak ho chcete zakázať.
proposal_answering_enabled: Odpovedanie na návrh je povolené
- proposal_edit_before_minutes: Návrhy môžu byť editované autormi až po uplynutí toľkoto minút
proposal_length: Maximálna dĺžka návrhu
proposal_limit: Limit návrhu na užívateľa
proposal_wizard_step_1_help_text: Pomocný text Sprievodcu "Vytvoriť" návrh
@@ -281,7 +280,6 @@ sk:
form:
note: Poznámka
submit: Predložiť
- leave_your_note: Nechajte svoju poznámku
title: Súkromné poznámky
proposals:
edit:
diff --git a/decidim-proposals/config/locales/sv.yml b/decidim-proposals/config/locales/sv.yml
index a146c46c63edc..94320491aeb1c 100644
--- a/decidim-proposals/config/locales/sv.yml
+++ b/decidim-proposals/config/locales/sv.yml
@@ -151,7 +151,6 @@ sv:
participatory_texts_enabled: Deltagartexter är aktiverade
participatory_texts_enabled_readonly: Det går inte att ändra denna inställning om det finns befintliga förslag. Skapa en ny `Förslagskomponent` om du vill aktivera funktionen, eller kasta alla importerade förslag under menyn `Deltagartexter` om du vill avaktivera den.
proposal_answering_enabled: Aktiverat svar på förslag
- proposal_edit_before_minutes: Förslag kan redigeras av författare inom så här många minuter
proposal_edit_time: Redigering av förslag
proposal_edit_time_choices:
infinite: Tillåt redigering av förslag utan tidsbegränsning
@@ -369,7 +368,6 @@ sv:
form:
note: Annteckning
submit: Skicka in
- leave_your_note: Lämna anteckningen
title: Privata anteckningar
proposals:
edit:
diff --git a/decidim-proposals/config/locales/tr-TR.yml b/decidim-proposals/config/locales/tr-TR.yml
index a1b92bf224b28..ee55395ecfbf7 100644
--- a/decidim-proposals/config/locales/tr-TR.yml
+++ b/decidim-proposals/config/locales/tr-TR.yml
@@ -137,7 +137,6 @@ tr:
participatory_texts_enabled: Katılımcı metinler etkinleştirildi
participatory_texts_enabled_readonly: Mevcut teklifler varsa bu ayarla etkileşim kurulamaz. Bu özelliği etkinleştirmek istiyorsanız lütfen yeni bir "Teklifler bileşeni" oluşturun veya devre dışı bırakmak istiyorsanız "Katılımcı Metinler" menüsünde içe aktarılan tüm teklifleri iptal edin.
proposal_answering_enabled: Teklif yanıtlama etkin
- proposal_edit_before_minutes: Teklifler, bu birkaç dakika geçmeden yazarlar tarafından düzenlenebilir
proposal_length: Maksimum teklif gövdesi uzunluğu
proposal_limit: Katılımcı başına teklif sınırı
proposal_wizard_step_1_help_text: Teklif sihirbazı "Oluştur" adımı yardım metni
@@ -339,7 +338,6 @@ tr:
form:
note: Not
submit: Gönder
- leave_your_note: Notunu bırak
title: Özel notlar
proposal_states:
create:
diff --git a/decidim-proposals/config/locales/uk.yml b/decidim-proposals/config/locales/uk.yml
index ae428dda000fb..4495d5f6af1e1 100644
--- a/decidim-proposals/config/locales/uk.yml
+++ b/decidim-proposals/config/locales/uk.yml
@@ -65,7 +65,6 @@ uk:
new_proposal_help_text: Підказки зі внесення нової пропозиції
official_proposals_enabled: Службові пропозиції увімкнено
proposal_answering_enabled: Увімкнено відповіді на пропозиції
- proposal_edit_before_minutes: Пропозиції можуть бути відредаговані авторами до того, як пройде стільки хвилин
proposal_length: Гранична довжина основного тексту пропозиції
proposal_limit: Гранична кількість пропозицій від одного учасника
proposal_wizard_step_1_help_text: Довідка майстра пропозицій щодо кроку "Створити"
@@ -131,7 +130,6 @@ uk:
form:
note: Примітка
submit: Надіслати
- leave_your_note: Залиште свою нотатку
title: Приватні примітки
proposals:
form:
diff --git a/decidim-proposals/config/locales/zh-CN.yml b/decidim-proposals/config/locales/zh-CN.yml
index a220de61e3ac5..b75475461f3c5 100644
--- a/decidim-proposals/config/locales/zh-CN.yml
+++ b/decidim-proposals/config/locales/zh-CN.yml
@@ -116,7 +116,6 @@ zh-CN:
participatory_texts_enabled: 参与性案文已启用
participatory_texts_enabled_readonly: 如果有现存的提议,无法与此设置进行交互。 请, 如果您想要启用此功能,或在"参与文本"菜单中放弃所有导入的提议,则创建一个新的 "建议组件"。
proposal_answering_enabled: 建议答案已启用
- proposal_edit_before_minutes: 建议可以由作者在这么多分钟过去之前编辑
proposal_length: 最大建议体长度
proposal_limit: 每个参与者的建议限制
proposal_wizard_step_1_help_text: 建议向导“创建”步骤帮助文本
@@ -294,7 +293,6 @@ zh-CN:
form:
note: 说明
submit: 提交
- leave_your_note: 留下您的便笺
title: 私人笔记
proposals:
edit:
diff --git a/decidim-proposals/config/locales/zh-TW.yml b/decidim-proposals/config/locales/zh-TW.yml
index e807611447835..90d3d7c229741 100644
--- a/decidim-proposals/config/locales/zh-TW.yml
+++ b/decidim-proposals/config/locales/zh-TW.yml
@@ -143,7 +143,6 @@ zh-TW:
participatory_texts_enabled: 參與式文字已啟用
participatory_texts_enabled_readonly: 如果已經存在提案,則無法與此設置互動。如果您想要啟用此功能,請創建一個新的“提案組件”,或者如果要禁用此功能,請在“參與式文字”選單中放棄所有已匯入的提案。
proposal_answering_enabled: 提案回答已啟用
- proposal_edit_before_minutes: 在幾分鐘後,作者可以編輯提案
proposal_edit_time: 編輯提案
proposal_edit_time_choices:
infinite: 允許無限時間編輯提案
@@ -191,10 +190,8 @@ zh-TW:
proposals:
admin:
proposal_note_created:
- email_intro: 有人在提案「%{resource_title}」上留了一則留言。在
管理員面板檢查它。
email_outro: 您收到此通知,因為您可以對提案進行評估。
email_subject: 有人在提案 %{resource_title} 上留下了一則註記。
- notification_title: 有人在提案「
%{resource_title}」上留了一則留言。請至
管理面板查看。
collaborative_draft_access_accepted:
email_intro: '%{requester_name} 已經被接受成為
%{resource_title} 協作草稿的貢獻者。'
email_outro: 您收到此通知,是因為您是
%{resource_title} 的協作者。
@@ -395,7 +392,6 @@ zh-TW:
form:
note: 附註
submit: 提交
- leave_your_note: 留下您的註記
title: 私有注解
proposals:
answer:
diff --git a/decidim-proposals/lib/decidim/proposals/admin_engine.rb b/decidim-proposals/lib/decidim/proposals/admin_engine.rb
index c42f3470f0396..0b237446345c6 100644
--- a/decidim-proposals/lib/decidim/proposals/admin_engine.rb
+++ b/decidim-proposals/lib/decidim/proposals/admin_engine.rb
@@ -18,6 +18,7 @@ class AdminEngine < ::Rails::Engine
post :update_category
post :publish_answers
post :update_scope
+ post :update_multiple_answers, controller: "proposal_answers"
resource :proposals_import, only: [:new, :create]
resource :proposals_merge, only: [:create]
resource :proposals_split, only: [:create]
diff --git a/decidim-proposals/lib/decidim/proposals/engine.rb b/decidim-proposals/lib/decidim/proposals/engine.rb
index fc949c39cf342..f9eb49ad2b096 100644
--- a/decidim-proposals/lib/decidim/proposals/engine.rb
+++ b/decidim-proposals/lib/decidim/proposals/engine.rb
@@ -22,6 +22,11 @@ class Engine < ::Rails::Engine
end
resource :proposal_vote, only: [:create, :destroy]
resources :versions, only: [:show]
+ resources :invite_coauthors, only: [:index, :create, :update, :destroy] do
+ collection do
+ delete :cancel
+ end
+ end
end
resources :collaborative_drafts, except: [:destroy] do
member do
diff --git a/decidim-proposals/spec/commands/decidim/proposals/accept_coauthorship_spec.rb b/decidim-proposals/spec/commands/decidim/proposals/accept_coauthorship_spec.rb
new file mode 100644
index 0000000000000..074b966b19a03
--- /dev/null
+++ b/decidim-proposals/spec/commands/decidim/proposals/accept_coauthorship_spec.rb
@@ -0,0 +1,110 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+module Decidim
+ module Proposals
+ describe AcceptCoauthorship do
+ let!(:proposal) { create(:proposal) }
+
+ let(:coauthor) { create(:user, organization: proposal.organization) }
+ let!(:notification) do
+ create(:notification, :proposal_coauthor_invite, resource: proposal, user: coauthor)
+ end
+ let!(:another_notification) do
+ create(:notification, :proposal_coauthor_invite, resource: proposal)
+ end
+
+ let(:command) { described_class.new(proposal, coauthor) }
+
+ describe "when the coauthor is valid" do
+ it "adds the coauthor to the proposal" do
+ expect do
+ command.call
+ end.to change { proposal.coauthorships.count }.by(1)
+ end
+
+ it "broadcasts :ok" do
+ expect { command.call }.to broadcast(:ok)
+ end
+
+ it "removes the notification" do
+ expect { command.call }.to change(Decidim::Notification, :count).by(-1)
+ expect(Decidim::Notification.all.to_a).to eq([another_notification])
+ end
+
+ it_behaves_like "fires an ActiveSupport::Notification event", "decidim.events.proposals.accepted_coauthorship"
+ it_behaves_like "fires an ActiveSupport::Notification event", "decidim.events.proposals.coauthor_accepted_invite"
+
+ it "notifies the coauthor and existing authors about the new coauthorship" do
+ expect(Decidim::EventsManager)
+ .to receive(:publish)
+ .with(
+ event: "decidim.events.proposals.coauthor_accepted_invite",
+ event_class: Decidim::Proposals::CoauthorAcceptedInviteEvent,
+ resource: proposal,
+ affected_users: proposal.authors.reject { |author| author == coauthor },
+ extra: { coauthor_id: coauthor.id }
+ )
+ expect(Decidim::EventsManager)
+ .to receive(:publish)
+ .with(
+ event: "decidim.events.proposals.accepted_coauthorship",
+ event_class: Decidim::Proposals::AcceptedCoauthorshipEvent,
+ resource: proposal,
+ affected_users: [coauthor]
+ )
+
+ command.call
+ end
+ end
+
+ describe "when the coauthor is not in the same organization" do
+ let(:coauthor) { create(:user) }
+
+ it "does not add the coauthor to the proposal" do
+ expect do
+ command.call
+ end.not_to(change { proposal.coauthorships.count })
+ end
+
+ it "broadcasts :invalid" do
+ expect { command.call }.to broadcast(:invalid)
+ end
+ end
+
+ describe "when the coauthor is already an author" do
+ let!(:coauthor) { create(:user, organization: proposal.organization) }
+
+ before do
+ proposal.add_coauthor(coauthor)
+ end
+
+ it "does not add the coauthor to the proposal" do
+ expect do
+ command.call
+ end.not_to(change { proposal.coauthorships.count })
+ end
+
+ it "broadcasts :invalid" do
+ expect { command.call }.to broadcast(:invalid)
+ end
+ end
+
+ describe "when the coauthor is nil" do
+ let(:coauthor) { nil }
+ let(:notification) { create(:notification, :proposal_coauthor_invite) }
+
+ it "does not add the coauthor to the proposal" do
+ expect do
+ command.call
+ end.not_to(change { proposal.coauthorships.count })
+ end
+
+ it "broadcasts :invalid" do
+ expect { command.call }.to broadcast(:invalid)
+ end
+ end
+ end
+ end
+end
diff --git a/decidim-proposals/spec/commands/decidim/proposals/cancel_coauthorship_spec.rb b/decidim-proposals/spec/commands/decidim/proposals/cancel_coauthorship_spec.rb
new file mode 100644
index 0000000000000..1dedc29d84d4d
--- /dev/null
+++ b/decidim-proposals/spec/commands/decidim/proposals/cancel_coauthorship_spec.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+module Decidim
+ module Proposals
+ describe CancelCoauthorship do
+ let!(:proposal) { create(:proposal) }
+
+ let(:coauthor) { create(:user, organization: proposal.organization) }
+ let!(:notification) do
+ create(:notification, :proposal_coauthor_invite, user: coauthor, resource: proposal)
+ end
+ let!(:another_notification) do
+ create(:notification, :proposal_coauthor_invite, resource: proposal)
+ end
+
+ let(:command) { described_class.new(proposal, coauthor) }
+
+ describe "when the coauthor is valid" do
+ it "broadcasts :ok" do
+ expect { command.call }.to broadcast(:ok)
+ end
+
+ it "removes the coauthor from the proposal" do
+ expect { command.call }.to change(Decidim::Notification, :count).by(-1)
+ expect(Decidim::Notification.all.to_a).to eq([another_notification])
+ end
+ end
+
+ describe "when the coauthor is not valid" do
+ let(:coauthor) { nil }
+ let(:notification) { create(:notification, :proposal_coauthor_invite, resource: proposal) }
+
+ it "broadcasts :invalid" do
+ expect { command.call }.to broadcast(:invalid)
+ end
+ end
+
+ describe "when the coauthor is already an author" do
+ let!(:coauthor) { create(:user, organization: proposal.organization) }
+
+ before do
+ proposal.add_coauthor(coauthor)
+ end
+
+ it "does not remove the coauthor from the proposal" do
+ expect do
+ command.call
+ end.not_to(change(Decidim::Notification, :count))
+ end
+ end
+ end
+ end
+end
diff --git a/decidim-proposals/spec/commands/decidim/proposals/invite_coauthor_spec.rb b/decidim-proposals/spec/commands/decidim/proposals/invite_coauthor_spec.rb
new file mode 100644
index 0000000000000..92ff6a8ab3075
--- /dev/null
+++ b/decidim-proposals/spec/commands/decidim/proposals/invite_coauthor_spec.rb
@@ -0,0 +1,59 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+module Decidim
+ module Proposals
+ describe InviteCoauthor do
+ let!(:proposal) { create(:proposal) }
+
+ let(:coauthor) { create(:user, organization: proposal.organization) }
+ let(:command) { described_class.new(proposal, coauthor) }
+
+ describe "when the coauthor is valid" do
+ it "broadcasts :ok" do
+ expect { command.call }.to broadcast(:ok)
+ end
+
+ it "generates a notification" do
+ perform_enqueued_jobs do
+ expect { command.call }.to change(Decidim::Notification, :count).by(1)
+ end
+ end
+
+ it_behaves_like "fires an ActiveSupport::Notification event", "decidim.events.proposals.coauthor_invited"
+
+ it "notifies the coauthor about the invitation" do
+ expect(Decidim::EventsManager)
+ .to receive(:publish)
+ .with(
+ event: "decidim.events.proposals.coauthor_invited",
+ event_class: Decidim::Proposals::CoauthorInvitedEvent,
+ resource: proposal,
+ affected_users: [coauthor]
+ )
+
+ command.call
+ end
+ end
+
+ describe "when the coauthor is already an author" do
+ before do
+ proposal.add_coauthor(coauthor)
+ end
+
+ it "does not generate a notification" do
+ expect { command.call }.not_to change(Decidim::Notification, :count)
+ end
+ end
+
+ describe "when the coauthor is nil" do
+ let(:coauthor) { nil }
+
+ it "broadcasts :invalid" do
+ expect { command.call }.to broadcast(:invalid)
+ end
+ end
+ end
+ end
+end
diff --git a/decidim-proposals/spec/commands/decidim/proposals/reject_coauthorship_spec.rb b/decidim-proposals/spec/commands/decidim/proposals/reject_coauthorship_spec.rb
new file mode 100644
index 0000000000000..eb9c578f47880
--- /dev/null
+++ b/decidim-proposals/spec/commands/decidim/proposals/reject_coauthorship_spec.rb
@@ -0,0 +1,81 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+module Decidim
+ module Proposals
+ describe RejectCoauthorship do
+ let!(:proposal) { create(:proposal) }
+
+ let(:coauthor) { create(:user, organization: proposal.organization) }
+ let(:command) { described_class.new(proposal, coauthor) }
+
+ let!(:notification) do
+ create(:notification, :proposal_coauthor_invite, user: coauthor, resource: proposal)
+ end
+
+ let!(:another_notification) do
+ create(:notification, :proposal_coauthor_invite, resource: proposal)
+ end
+
+ describe "when the coauthor is valid" do
+ it "broadcasts :ok" do
+ expect { command.call }.to broadcast(:ok)
+ end
+
+ it "removes the notification" do
+ expect { command.call }.to change(Decidim::Notification, :count).by(-1)
+ expect(Decidim::Notification.all.to_a).to eq([another_notification])
+ end
+
+ it_behaves_like "fires an ActiveSupport::Notification event", "decidim.events.proposals.rejected_coauthorship"
+ it_behaves_like "fires an ActiveSupport::Notification event", "decidim.events.proposals.coauthor_rejected_invite"
+
+ it "notifies the coauthor and existing authors about the new coauthorship" do
+ expect(Decidim::EventsManager)
+ .to receive(:publish)
+ .with(
+ event: "decidim.events.proposals.coauthor_rejected_invite",
+ event_class: Decidim::Proposals::CoauthorRejectedInviteEvent,
+ resource: proposal,
+ affected_users: proposal.authors,
+ extra: { coauthor_id: coauthor.id }
+ )
+ expect(Decidim::EventsManager)
+ .to receive(:publish)
+ .with(
+ event: "decidim.events.proposals.rejected_coauthorship",
+ event_class: Decidim::Proposals::RejectedCoauthorshipEvent,
+ resource: proposal,
+ affected_users: [coauthor]
+ )
+
+ command.call
+ end
+ end
+
+ describe "when the coauthor is nil" do
+ let(:coauthor) { nil }
+ let(:notification) { create(:notification, :proposal_coauthor_invite, resource: proposal) }
+
+ it "broadcasts :invalid" do
+ expect { command.call }.to broadcast(:invalid)
+ end
+ end
+
+ describe "when the coauthor is already an author" do
+ let!(:coauthor) { create(:user, organization: proposal.organization) }
+
+ before do
+ proposal.add_coauthor(coauthor)
+ end
+
+ it "does not remove the coauthor from the proposal" do
+ expect do
+ command.call
+ end.not_to(change(Decidim::Notification, :count))
+ end
+ end
+ end
+ end
+end
diff --git a/decidim-proposals/spec/controllers/decidim/proposals/admin/proposal_answers_controller_spec.rb b/decidim-proposals/spec/controllers/decidim/proposals/admin/proposal_answers_controller_spec.rb
new file mode 100644
index 0000000000000..fd2d6fade81ff
--- /dev/null
+++ b/decidim-proposals/spec/controllers/decidim/proposals/admin/proposal_answers_controller_spec.rb
@@ -0,0 +1,119 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+require "decidim/templates/test/factories"
+
+module Decidim
+ module Proposals
+ module Admin
+ describe ProposalAnswersController do
+ routes { Decidim::Proposals::AdminEngine.routes }
+
+ let(:user) { create(:user, :confirmed, :admin, organization: component.organization) }
+ let(:component) { create(:proposal_component, :with_creation_enabled, :with_attachments_allowed) }
+ let!(:emendation) { create(:proposal, component:) }
+ let!(:amendment) { create(:amendment, amendable: proposal2, emendation:) }
+ let(:proposal1) { create(:proposal, cost: nil, component:, proposal_state: nil) }
+ let(:proposal2) { create(:proposal, cost: nil, component:, proposal_state: nil) }
+ let(:proposal_state) { create(:proposal_state, component:) }
+ let(:template) { create(:template, skip_injection: true, target: :proposal_answer, templatable: component, field_values: { "proposal_state_id" => proposal_state.id }) }
+ let(:proposal_ids) { [proposal1.id, proposal2.id] }
+ let(:params) do
+ {
+ proposal_ids:, template: { template_id: template.id }
+ }
+ end
+ let(:context) do
+ {
+ current_organization: component.organization,
+ current_component: component,
+ current_user: user
+ }
+ end
+
+ before do
+ sign_in user
+ request.env["decidim.current_organization"] = component.organization
+ request.env["decidim.current_component"] = component
+ end
+
+ describe "POST update_multiple_answers" do
+ it "enqueues ProposalAnswerJob for each proposal and redirects" do
+ expect { post :update_multiple_answers, params: }.to have_enqueued_job(ProposalAnswerJob).exactly(2).times
+
+ expect(response).to redirect_to(Decidim::EngineRouter.admin_proxy(component).root_path)
+ expect(flash[:notice]).to include("2 proposals will be answered using the template \"#{template.name["en"]}\".")
+ expect(flash[:alert]).to be_nil
+ end
+
+ context "when some proposal fails" do
+ before do
+ valid = false
+ # rubocop:disable RSpec/AnyInstance
+ allow_any_instance_of(Decidim::Proposals::Admin::ProposalAnswerForm).to receive(:valid?) do |_arg|
+ valid = !valid
+ end
+ # rubocop:enable RSpec/AnyInstance
+ end
+
+ it "enqueues ProposalAnswerJob once and redirects" do
+ expect { post :update_multiple_answers, params: }.to have_enqueued_job(ProposalAnswerJob).exactly(1).times
+
+ expect(response).to redirect_to(Decidim::EngineRouter.admin_proxy(component).root_path)
+ expect(flash[:notice]).to include("1 proposals will be answered using the template \"#{template.name["en"]}\".")
+ expect(flash[:alert]).to include("could not be answered due errors applying the template \"#{template.name["en"]}\".")
+ end
+ end
+
+ context "when proposal is an emendation" do
+ let(:proposal1) { emendation }
+
+ it "enqueues ProposalAnswerJob once and redirects" do
+ expect { post :update_multiple_answers, params: }.to have_enqueued_job(ProposalAnswerJob).exactly(1).times
+
+ expect(response).to redirect_to(Decidim::EngineRouter.admin_proxy(component).root_path)
+ expect(flash[:notice]).to include("1 proposals will be answered using the template \"#{template.name["en"]}\".")
+ expect(flash[:alert]).to include("Proposals with IDs [#{proposal1.id}] could not be answered due errors applying the template \"#{template.name["en"]}\".")
+ end
+ end
+
+ context "when cost is required" do
+ before do
+ component.update!(
+ step_settings: {
+ component.participatory_space.active_step.id => {
+ answers_with_costs: true
+ }
+ }
+ )
+ end
+
+ let(:proposal_state) { Decidim::Proposals::ProposalState.find_by(token: :accepted) }
+
+ it "redirects with an alert" do
+ expect { post :update_multiple_answers, params: }.not_to have_enqueued_job(ProposalAnswerJob)
+
+ expect(response).to redirect_to(Decidim::EngineRouter.admin_proxy(component).root_path)
+ expect(flash[:alert]).to include("could not be answered due errors applying the template \"#{template.name["en"]}\".")
+ expect(flash[:notice]).to be_nil
+ end
+ end
+
+ context "when templates is not installed" do
+ before do
+ allow(Decidim).to receive(:module_installed?).with(:templates).and_return(false)
+ end
+
+ it "redirects with an alert" do
+ expect { post :update_multiple_answers, params: }.not_to have_enqueued_job(ProposalAnswerJob)
+
+ expect(response).to redirect_to(Decidim::EngineRouter.admin_proxy(component).root_path)
+ expect(flash[:alert]).to include("could not be answered due errors")
+ expect(flash[:notice]).to be_nil
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/decidim-proposals/spec/events/decidim/proposals/accepted_coauthorship_event_spec.rb b/decidim-proposals/spec/events/decidim/proposals/accepted_coauthorship_event_spec.rb
new file mode 100644
index 0000000000000..db31a24df2268
--- /dev/null
+++ b/decidim-proposals/spec/events/decidim/proposals/accepted_coauthorship_event_spec.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+module Decidim
+ module Proposals
+ describe AcceptedCoauthorshipEvent do
+ let(:resource) { create(:proposal) }
+ let(:participatory_process) { create(:participatory_process, organization:) }
+ let(:proposal_component) { create(:proposal_component, participatory_space: participatory_process) }
+ let(:resource_title) { decidim_sanitize_translated(resource.title) }
+ let(:event_name) { "decidim.events.proposals.accepted_coauthorship" }
+
+ let(:notification_title) do
+ "You have been added as a co-author of the proposal
#{resource_title}."
+ end
+
+ include_context "when a simple event"
+
+ it_behaves_like "a simple event notification"
+ it_behaves_like "a notification event only"
+ end
+ end
+end
diff --git a/decidim-proposals/spec/events/decidim/proposals/coauthor_accepted_invite_event_spec.rb b/decidim-proposals/spec/events/decidim/proposals/coauthor_accepted_invite_event_spec.rb
new file mode 100644
index 0000000000000..3546358fd201a
--- /dev/null
+++ b/decidim-proposals/spec/events/decidim/proposals/coauthor_accepted_invite_event_spec.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+module Decidim
+ module Proposals
+ describe CoauthorAcceptedInviteEvent do
+ include_context "when a simple event"
+
+ let(:resource) { create(:proposal) }
+ let(:extra) do
+ {
+ "coauthor_id" => coauthor.id
+ }
+ end
+ let(:notification_title) do
+ "
#{coauthor.name} has accepted your invitation to become a co-author of the proposal
#{resource_title}."
+ end
+ let(:participatory_process) { create(:participatory_process, organization:) }
+ let(:proposal_component) { create(:proposal_component, participatory_space: participatory_process) }
+ let(:resource_title) { decidim_sanitize_translated(resource.title) }
+ let(:event_name) { "decidim.events.proposals.coauthor_accepted_invite" }
+ let(:coauthor) { create(:user, organization: resource.organization) }
+
+ it_behaves_like "a simple event notification"
+ it_behaves_like "a notification event only"
+ end
+ end
+end
diff --git a/decidim-proposals/spec/events/decidim/proposals/coauthor_invited_event_spec.rb b/decidim-proposals/spec/events/decidim/proposals/coauthor_invited_event_spec.rb
new file mode 100644
index 0000000000000..37d3d6e4dcf77
--- /dev/null
+++ b/decidim-proposals/spec/events/decidim/proposals/coauthor_invited_event_spec.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+module Decidim
+ module Proposals
+ describe CoauthorInvitedEvent do
+ let(:resource) { create(:proposal) }
+ let(:participatory_process) { create(:participatory_process, organization:) }
+ let(:proposal_component) { create(:proposal_component, participatory_space: participatory_process) }
+ let(:resource_title) { decidim_sanitize_translated(resource.title) }
+ let(:event_name) { "decidim.events.proposals.coauthor_invited" }
+
+ include_context "when a simple event"
+
+ it_behaves_like "a simple event"
+
+ describe "email_subject" do
+ context "when resource title contains apostrophes" do
+ let(:resource) { create(:proposal) }
+
+ it "is generated correctly" do
+ expect(subject.email_subject).to eq("You have been invited to be a co-author of the proposal \"#{resource_title}\"")
+ end
+ end
+
+ it "is generated correctly" do
+ expect(subject.email_subject).to eq("You have been invited to be a co-author of the proposal \"#{resource_title}\"")
+ end
+ end
+
+ describe "email_intro" do
+ it "is generated correctly" do
+ expect(subject.email_intro)
+ .to eq("You have been invited to be a co-author of the proposal \"#{resource_title}\". You can accept or decline the invitation in this page:")
+ end
+ end
+
+ describe "email_outro" do
+ it "is generated correctly" do
+ expect(subject.email_outro)
+ .to eq("You have received this notification because the author of the proposal wants to recognize your contributions by becoming a co-author.")
+ end
+ end
+
+ describe "notification_title" do
+ it "is generated correctly" do
+ expect(subject.notification_title)
+ .to eq("
#{author.name} would like to invite you as a co-author of the proposal
#{resource_title}.")
+ end
+ end
+ end
+ end
+end
diff --git a/decidim-proposals/spec/events/decidim/proposals/coauthor_rejected_invite_event_spec.rb b/decidim-proposals/spec/events/decidim/proposals/coauthor_rejected_invite_event_spec.rb
new file mode 100644
index 0000000000000..f8cd640d94557
--- /dev/null
+++ b/decidim-proposals/spec/events/decidim/proposals/coauthor_rejected_invite_event_spec.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+module Decidim
+ module Proposals
+ describe CoauthorRejectedInviteEvent do
+ include_context "when a simple event"
+
+ let(:resource) { create(:proposal) }
+ let(:extra) do
+ {
+ "coauthor_id" => coauthor.id
+ }
+ end
+ let(:notification_title) do
+ "
#{coauthor.name} has declined your invitation to become a co-author of the proposal
#{resource_title}."
+ end
+ let(:participatory_process) { create(:participatory_process, organization:) }
+ let(:proposal_component) { create(:proposal_component, participatory_space: participatory_process) }
+ let(:resource_title) { decidim_sanitize_translated(resource.title) }
+ let(:event_name) { "decidim.events.proposals.coauthor_rejected_invite" }
+ let(:coauthor) { create(:user, organization: resource.organization) }
+
+ it_behaves_like "a simple event notification"
+ it_behaves_like "a notification event only"
+ end
+ end
+end
diff --git a/decidim-proposals/spec/events/decidim/proposals/rejected_coauthorship_event_spec.rb b/decidim-proposals/spec/events/decidim/proposals/rejected_coauthorship_event_spec.rb
new file mode 100644
index 0000000000000..3f19e41908618
--- /dev/null
+++ b/decidim-proposals/spec/events/decidim/proposals/rejected_coauthorship_event_spec.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+module Decidim
+ module Proposals
+ describe RejectedCoauthorshipEvent do
+ let(:resource) { create(:proposal) }
+ let(:participatory_process) { create(:participatory_process, organization:) }
+ let(:proposal_component) { create(:proposal_component, participatory_space: participatory_process) }
+ let(:resource_title) { decidim_sanitize_translated(resource.title) }
+ let(:event_name) { "decidim.events.proposals.rejected_coauthorship" }
+
+ let(:notification_title) do
+ "You have declined the invitation from
#{author.name} to become a co-author of the proposal
#{resource_title}."
+ end
+
+ include_context "when a simple event"
+ it_behaves_like "a simple event notification"
+ it_behaves_like "a notification event only"
+ end
+ end
+end
diff --git a/decidim-proposals/spec/jobs/decidim/proposals/admin/proposal_answer_job_spec.rb b/decidim-proposals/spec/jobs/decidim/proposals/admin/proposal_answer_job_spec.rb
new file mode 100644
index 0000000000000..fabc7fc9d5bf1
--- /dev/null
+++ b/decidim-proposals/spec/jobs/decidim/proposals/admin/proposal_answer_job_spec.rb
@@ -0,0 +1,62 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+describe Decidim::Proposals::Admin::ProposalAnswerJob do
+ subject { described_class }
+
+ let(:component) { create(:proposal_component, :with_creation_enabled) }
+ let(:organization) { component.organization }
+ let(:user) { create(:user, :admin, :confirmed, organization:) }
+ let(:old_state) { create(:proposal_state, component:, token: "old_state") }
+ let(:proposal) { create(:proposal, component:, proposal_state: old_state) }
+ let(:new_state) do
+ create(
+ :proposal_state,
+ title: { en: "Custom state" },
+ token: "custom_state",
+ component:
+ )
+ end
+
+ let(:attributes) do
+ {
+ "answer" => { "en" => "Test answer" },
+ "internal_state" => new_state.token
+ }
+ end
+
+ let(:context) do
+ {
+ current_organization: organization,
+ current_component: component,
+ current_user: user
+ }
+ end
+
+ describe "#perform" do
+ before do
+ subject.perform_now(proposal, attributes, context)
+ proposal.reload
+ end
+
+ it "updates the proposal answer" do
+ expect(proposal.answer).to eq({ "en" => "Test answer" })
+ expect(proposal.proposal_state).to eq(new_state)
+ end
+
+ context "when the answer is invalid" do
+ let(:attributes) do
+ {
+ "answer" => { "en" => "Test answer" },
+ "internal_state" => "a-state-that-does-not-exist"
+ }
+ end
+
+ it "does not update the proposal answer" do
+ expect(proposal.answer).not_to eq({ "en" => "Test answer" })
+ expect(proposal.proposal_state).not_to eq(new_state)
+ end
+ end
+ end
+end
diff --git a/decidim-proposals/spec/models/decidim/proposals/proposal_spec.rb b/decidim-proposals/spec/models/decidim/proposals/proposal_spec.rb
index 2fef38f16a1f7..269b6b06f4c91 100644
--- a/decidim-proposals/spec/models/decidim/proposals/proposal_spec.rb
+++ b/decidim-proposals/spec/models/decidim/proposals/proposal_spec.rb
@@ -269,6 +269,91 @@ module Proposals
expect(results).to eq([assigned_proposal])
end
end
+
+ describe "#coauthor_invitations_for" do
+ let!(:notification) do
+ create(:notification, :proposal_coauthor_invite, resource: proposal, user: coauthor)
+ end
+ let(:coauthor) { create(:user, organization:) }
+
+ it "returns the coauthor invitations for the given user" do
+ expect(proposal.coauthor_invitations_for(coauthor)).to eq([notification])
+ end
+
+ context "when the user has not been invited" do
+ it "returns empty" do
+ expect(proposal.coauthor_invitations_for(create(:user))).to be_empty
+ end
+ end
+
+ context "when the user the notification is for another event" do
+ let!(:notification) do
+ create(:notification, event_class: "Decidim::Proposals::AnotherEvent", resource: proposal, user: coauthor)
+ end
+
+ it "returns empty" do
+ expect(proposal.coauthor_invitations_for(coauthor)).to be_empty
+ end
+ end
+ end
+
+ describe "#actions_for_comment" do
+ let(:proposal) { create(:proposal, component:) }
+ let(:author) { create(:user, :confirmed, organization: component.organization) }
+ let(:comment) { create(:comment, author:, commentable: proposal) }
+
+ it "returns actions to invite the comment author as a co-author" do
+ expect(proposal.actions_for_comment(comment, proposal.creator_author)).to eq([
+ {
+ label: "Mark as co-author",
+ url: EngineRouter.main_proxy(component).proposal_invite_coauthors_path(proposal_id: proposal.id, id: comment.author.id),
+ icon: "user-add-line",
+ method: :post,
+ data: {
+ confirm: "Are you sure you want to mark this user as a co-author? The receiver will receive a notification to accept or decline the invitation."
+ }
+ }
+ ])
+ end
+
+ context "when the requester user is not the author of the proposal" do
+ it "returns nil" do
+ expect(proposal.actions_for_comment(comment, create(:user))).to be_nil
+ end
+ end
+
+ context "when no requester" do
+ it "returns nil" do
+ expect(proposal.actions_for_comment(comment, nil)).to be_nil
+ end
+ end
+
+ context "when the author has already been invited" do
+ let!(:notification) do
+ create(:notification, :proposal_coauthor_invite, resource: proposal, user: comment.author)
+ end
+
+ it "returns actions to remove the co-author invitation" do
+ expect(proposal.actions_for_comment(comment, proposal.creator_author)).to eq([
+ {
+ label: "Cancel co-author invitation",
+ url: EngineRouter.main_proxy(component).cancel_proposal_invite_coauthors_path(proposal_id: proposal.id, id: comment.author.id),
+ icon: "user-forbid-line",
+ method: :delete,
+ data: {
+ confirm: "Are you sure you want to cancel the co-author invitation?"
+ }
+ }
+ ])
+ end
+
+ context "when the requester user is not the author of the proposal" do
+ it "returns nil" do
+ expect(proposal.actions_for_comment(comment, create(:user))).to be_nil
+ end
+ end
+ end
+ end
end
end
end
diff --git a/decidim-proposals/spec/models/decidim/proposals/proposal_state_spec.rb b/decidim-proposals/spec/models/decidim/proposals/proposal_state_spec.rb
index 060394366bb23..d540f132f9183 100644
--- a/decidim-proposals/spec/models/decidim/proposals/proposal_state_spec.rb
+++ b/decidim-proposals/spec/models/decidim/proposals/proposal_state_spec.rb
@@ -9,16 +9,47 @@ module Proposals
let(:component) { build(:proposal_component) }
let(:organization) { component.participatory_space.organization }
- let(:proposal_state) { create(:proposal_state, component:) }
+ let(:proposal_state) { create(:proposal_state, token:, component:) }
+ let!(:proposal) { create(:proposal, component:) }
+ let(:token) { "some_status" }
it { is_expected.to be_valid }
it { is_expected.to be_versioned }
- describe "system" do
- let(:proposal_state) { create(:proposal_state, :accepted, component:) }
+ context "when creating" do
+ let(:proposal_state) { build(:proposal_state, token:, component:) }
- it "prevents deletion" do
- expect { proposal_state.destroy }.not_to change(Decidim::Proposals::ProposalState, :count)
+ it "does not generate a new token if exists" do
+ expect(proposal_state.token).to eq("some_status")
+ proposal_state.update!(title: { en: "New title" })
+ expect(proposal_state.token).to be_present
+ expect(proposal_state.token).to eq("some_status")
+ end
+ end
+
+ context "when no token" do
+ let(:token) { nil }
+
+ it "generates a token on creation" do
+ proposal_state.save!
+ expect(proposal_state.token).to be_present
+ end
+ end
+
+ context "when destroying" do
+ it "destroys the proposal state" do
+ proposal_state.destroy
+ expect { proposal_state.reload }.to raise_error(ActiveRecord::RecordNotFound)
+ end
+
+ context "when proposals assigned" do
+ before do
+ proposal.update!(proposal_state:)
+ end
+
+ it "prevents deletion" do
+ expect { proposal_state.destroy! }.to raise_error(ActiveRecord::RecordNotDestroyed)
+ end
end
end
end
diff --git a/decidim-proposals/spec/permissions/decidim/proposals/permissions_spec.rb b/decidim-proposals/spec/permissions/decidim/proposals/permissions_spec.rb
index eafe6abddc948..6149b42923f24 100644
--- a/decidim-proposals/spec/permissions/decidim/proposals/permissions_spec.rb
+++ b/decidim-proposals/spec/permissions/decidim/proposals/permissions_spec.rb
@@ -11,9 +11,11 @@
current_component: proposal_component,
current_settings:,
proposal:,
- component_settings:
+ component_settings:,
+ coauthor:
}
end
+ let(:coauthor) { nil }
let(:proposal_component) { create(:proposal_component) }
let(:proposal) { create(:proposal, component: proposal_component) }
let(:component_settings) do
@@ -230,4 +232,162 @@
it { is_expected.to be true }
end
end
+
+ context "when inviting coauthor" do
+ let(:action) do
+ { scope: :public, action: :invite, subject: :proposal_coauthor_invites }
+ end
+ let(:coauthor) { create(:user, :confirmed, organization: user.organization) }
+ let!(:comment) { create(:comment, commentable: proposal, author: coauthor) }
+
+ shared_examples "coauthor is invitable" do
+ it { is_expected.to be true }
+
+ context "when already an author" do
+ before do
+ proposal.add_coauthor(coauthor)
+ end
+
+ it { is_expected.to be false }
+ end
+
+ context "when the current user is not the author" do
+ let(:user) { create(:user, :confirmed, organization: proposal.organization) }
+
+ it { is_expected.to be false }
+ end
+
+ context "when no comments" do
+ let!(:comment) { nil }
+
+ it { is_expected.to be false }
+ end
+
+ context "when coauthor not in comments" do
+ let!(:comment) { create(:comment, commentable: proposal) }
+
+ it { is_expected.to be false }
+ end
+
+ context "when coauthor is not confirmed" do
+ let(:coauthor) { create(:user, organization: user.organization) }
+
+ it { is_expected.to be false }
+ end
+
+ context "when coauthor is blocked" do
+ let(:coauthor) { create(:user, :blocked, organization: user.organization) }
+
+ it { is_expected.to be false }
+ end
+
+ context "when coauthor is deleted" do
+ let(:coauthor) { create(:user, :deleted, organization: user.organization) }
+
+ it { is_expected.to be false }
+ end
+ end
+
+ it_behaves_like "coauthor is invitable"
+
+ context "when a notification for the coauthor already exists" do
+ let!(:notification) { create(:notification, :proposal_coauthor_invite, user: coauthor) }
+
+ it { is_expected.to be true }
+ end
+
+ context "when notification exists for the same proposal" do
+ let!(:notification) { create(:notification, :proposal_coauthor_invite, user: coauthor, resource: proposal) }
+
+ it { is_expected.to be false }
+ end
+
+ context "when notification is for another user" do
+ let!(:notification) { create(:notification, :proposal_coauthor_invite, resource: proposal) }
+
+ it { is_expected.to be true }
+ end
+
+ context "when canceling invitation" do
+ let(:action) do
+ { scope: :public, action: :cancel, subject: :proposal_coauthor_invites }
+ end
+ let!(:notification) { create(:notification, :proposal_coauthor_invite, resource: proposal, user: coauthor) }
+
+ it_behaves_like "coauthor is invitable"
+ end
+ end
+
+ context "when coauthor is invited" do
+ let(:action) do
+ { scope: :public, action: :accept, subject: :proposal_coauthor_invites }
+ end
+ let(:user) { create(:user, :confirmed, organization: proposal.organization) }
+ let(:coauthor) { user }
+ let!(:notification) { create(:notification, :proposal_coauthor_invite, resource: proposal, user: coauthor) }
+
+ shared_examples "can accept coauthor" do
+ it { is_expected.to be true }
+
+ context "when already an author" do
+ before do
+ proposal.add_coauthor(coauthor)
+ end
+
+ it { is_expected.to be false }
+ end
+
+ context "when the user is not the coauthor" do
+ let(:coauthor) { create(:user, :confirmed, organization: proposal.organization) }
+
+ it { is_expected.to be false }
+ end
+
+ context "when no invitation" do
+ let!(:notification) { nil }
+
+ it { is_expected.to be false }
+ end
+
+ context "when notification is not for the same proposal" do
+ let!(:notification) { create(:notification, :proposal_coauthor_invite, user: coauthor) }
+
+ it { is_expected.to be false }
+ end
+
+ context "when notification is for another coauthor" do
+ let!(:notification) { create(:notification, :proposal_coauthor_invite, resource: proposal) }
+
+ it { is_expected.to be false }
+ end
+
+ context "when coauthor is blocked" do
+ let(:coauthor) { create(:user, :blocked, organization: proposal.organization) }
+
+ it { is_expected.to be false }
+ end
+
+ context "when coauthor is deleted" do
+ let(:coauthor) { create(:user, :deleted, organization: proposal.organization) }
+
+ it { is_expected.to be false }
+ end
+
+ context "when coauthor is not confirmed" do
+ let(:coauthor) { create(:user, organization: proposal.organization) }
+
+ it { is_expected.to be false }
+ end
+ end
+
+ it_behaves_like "can accept coauthor"
+
+ context "when declining invitation" do
+ let(:action) do
+ { scope: :public, action: :decline, subject: :proposal_coauthor_invites }
+ end
+
+ it_behaves_like "can accept coauthor"
+ end
+ end
end
diff --git a/decidim-proposals/spec/shared/merge_proposals_examples.rb b/decidim-proposals/spec/shared/merge_proposals_examples.rb
index d8885733a1c1e..4f5ee27770c3c 100644
--- a/decidim-proposals/spec/shared/merge_proposals_examples.rb
+++ b/decidim-proposals/spec/shared/merge_proposals_examples.rb
@@ -73,7 +73,7 @@
it "does not create a new proposal and displays a validation fail message" do
expect(page).to have_css(".table-list tbody tr", count: 3)
- expect(page).to have_content("There has been a problem merging the selected proposals")
+ expect(page).to have_content("There was a problem merging the selected proposals")
expect(page).to have_content("Are not official")
expect(page).to have_content("Have received votes or endorsements")
end
diff --git a/decidim-proposals/spec/shared/proposals_wizards_examples.rb b/decidim-proposals/spec/shared/proposals_wizards_examples.rb
index 282ec4d72e396..f521e9c0b6e3d 100644
--- a/decidim-proposals/spec/shared/proposals_wizards_examples.rb
+++ b/decidim-proposals/spec/shared/proposals_wizards_examples.rb
@@ -93,7 +93,7 @@
end
it "redirects to edit the proposal draft" do
- expect(page).to have_content("Edit Proposal Draft")
+ expect(page).to have_content("Edit proposal draft")
end
end
@@ -239,7 +239,7 @@
end
it "redirects to edit the proposal draft" do
- expect(page).to have_content("Edit Proposal Draft")
+ expect(page).to have_content("Edit proposal draft")
end
end
diff --git a/decidim-proposals/spec/shared/split_proposals_examples.rb b/decidim-proposals/spec/shared/split_proposals_examples.rb
index 9591d65cc3046..17194ccef14ae 100644
--- a/decidim-proposals/spec/shared/split_proposals_examples.rb
+++ b/decidim-proposals/spec/shared/split_proposals_examples.rb
@@ -58,7 +58,7 @@
let!(:proposals) { create_list(:proposal, 3, :with_endorsements, :with_votes, component: current_component) }
it "does not create a new proposal and displays a validation fail message" do
- expect(page).to have_content("There has been a problem splitting the selected proposals")
+ expect(page).to have_content("There was a problem splitting the selected proposals")
expect(page).to have_content("Are not official")
expect(page).to have_content("Have received votes or endorsements")
end
diff --git a/decidim-proposals/spec/system/admin/admin_manages_proposal_states_spec.rb b/decidim-proposals/spec/system/admin/admin_manages_proposal_states_spec.rb
index 949f9f667c356..1078055ef2b86 100644
--- a/decidim-proposals/spec/system/admin/admin_manages_proposal_states_spec.rb
+++ b/decidim-proposals/spec/system/admin/admin_manages_proposal_states_spec.rb
@@ -110,12 +110,12 @@
{
title: { "en" => "Editable state" },
announcement_title: { "en" => "Editable announcement title" },
- token: "editable",
+ token: "editable_state",
bg_color: "#EBF9FF",
text_color: "#0851A6"
}
end
- let!(:state) { create(:proposal_state, component: current_component, **state_params) }
+ let!(:proposal_state) { create(:proposal_state, component: current_component, **state_params) }
let(:attributes) { attributes_for(:proposal_state) }
before do
@@ -127,7 +127,7 @@
end
it "updates a proposal state" do
- within "tr", text: translated(state.title) do
+ within "tr", text: translated(proposal_state.title) do
click_on "Edit"
end
@@ -159,7 +159,7 @@
end
it "updates the label and announcement previews" do
- within "tr", text: translated(state.title) do
+ within "tr", text: translated(proposal_state.title) do
click_on "Edit"
end
diff --git a/decidim-proposals/spec/system/admin/admin_manages_proposals_spec.rb b/decidim-proposals/spec/system/admin/admin_manages_proposals_spec.rb
index b1c130999faac..74d30732837ce 100644
--- a/decidim-proposals/spec/system/admin/admin_manages_proposals_spec.rb
+++ b/decidim-proposals/spec/system/admin/admin_manages_proposals_spec.rb
@@ -27,6 +27,6 @@
it_behaves_like "publish answers"
it_behaves_like "sorted moderations" do
- let!(:reportables) { create_list(:proposal, 17, component: current_component) }
+ let!(:reportables) { create_list(:proposal, 27, component: current_component) }
end
end
diff --git a/decidim-proposals/spec/system/amendable/amend_proposal_spec.rb b/decidim-proposals/spec/system/amendable/amend_proposal_spec.rb
index 9d8b3d3cc0ad7..1d56de2197723 100644
--- a/decidim-proposals/spec/system/amendable/amend_proposal_spec.rb
+++ b/decidim-proposals/spec/system/amendable/amend_proposal_spec.rb
@@ -255,7 +255,7 @@
end
it "is shown the Error Flash" do
- expect(page).to have_css("[data-alert-box].alert", text: "An error ocurred while creating the amendment")
+ expect(page).to have_css("[data-alert-box].alert", text: "There was a problem creating the amendment")
end
it "is shown the field error message" do
diff --git a/decidim-proposals/spec/system/edit_proposal_spec.rb b/decidim-proposals/spec/system/edit_proposal_spec.rb
index a24aba7156ca2..23cecd7352d8d 100644
--- a/decidim-proposals/spec/system/edit_proposal_spec.rb
+++ b/decidim-proposals/spec/system/edit_proposal_spec.rb
@@ -186,7 +186,7 @@
end
end
- context "with geocoding enabled" do
+ context "with maps enabled" do
let(:component) { create(:proposal_component, :with_geocoding_enabled, participatory_space: participatory_process) }
let(:address) { "6 Villa des Nymphéas 75020 Paris" }
let(:new_address) { "6 rue Sorbier 75020 Paris" }
diff --git a/decidim-proposals/spec/system/new_proposals_spec.rb b/decidim-proposals/spec/system/new_proposals_spec.rb
index 474fdd94e83ef..8d140a7d460de 100644
--- a/decidim-proposals/spec/system/new_proposals_spec.rb
+++ b/decidim-proposals/spec/system/new_proposals_spec.rb
@@ -43,9 +43,9 @@
it "has helper character counter" do
within "form.new_proposal" do
- editor = find(".editor")
- page.scroll_to(editor)
- expect(editor.sibling("[id^=characters_]:not([id$=_sr])")).to have_content("At least 15 characters", count: 1)
+ within ".editor .input-character-counter__text" do
+ expect(page).to have_content("At least 15 characters", count: 1)
+ end
end
end
diff --git a/decidim-proposals/spec/system/proposal_comment_actions_spec.rb b/decidim-proposals/spec/system/proposal_comment_actions_spec.rb
new file mode 100644
index 0000000000000..6bce6b53c0d39
--- /dev/null
+++ b/decidim-proposals/spec/system/proposal_comment_actions_spec.rb
@@ -0,0 +1,129 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+describe "Interact with commenters" do
+ include_context "with a component"
+ let(:manifest_name) { "proposals" }
+ let(:proposal) { create(:proposal, users: [user], component:) }
+ let(:commenter) { create(:user, :confirmed, organization:) }
+ let!(:comment) { create(:comment, commentable: proposal, author: commenter) }
+ let!(:author_comment) { create(:comment, commentable: proposal, author: user) }
+
+ def visit_proposal
+ visit resource_locator(proposal).path
+ end
+
+ context "when author" do
+ before do
+ login_as user, scope: :user
+ visit_proposal
+ end
+
+ context "when the user is the commenter" do
+ it "has no actions" do
+ within "#comment_#{author_comment.id}" do
+ click_on "…"
+ expect(page).to have_no_content("Mark as co-author")
+ end
+ end
+ end
+
+ context "when the user is not the commenter" do
+ let(:notification) { Decidim::Notification.last }
+
+ it "author can invite" do
+ expect(page).to have_content("2 comments")
+ within "#comment_#{comment.id}" do
+ click_on "…"
+ perform_enqueued_jobs do
+ accept_confirm { click_on("Mark as co-author") }
+ end
+ end
+
+ expect(page).to have_content("successfully invited as a co-author")
+
+ within "#comment_#{comment.id}" do
+ click_on "…"
+ expect(page).to have_link("Cancel co-author invitation")
+ expect(page).to have_no_content("Mark as co-author")
+ end
+
+ expect(notification.event_class).to eq("Decidim::Proposals::CoauthorInvitedEvent")
+ expect(notification.resource).to eq(proposal)
+ expect(notification.user).to eq(commenter)
+ # sends email to commenter
+ expect(last_email.to).to include(commenter.email)
+ end
+ end
+
+ context "when a notification already exists" do
+ let!(:notification) { create(:notification, :proposal_coauthor_invite, user: commenter, resource: proposal) }
+
+ it "author can cancel invitation" do
+ within "#comment_#{comment.id}" do
+ click_on "…"
+ perform_enqueued_jobs do
+ accept_confirm { click_on("Cancel co-author invitation") }
+ end
+ end
+
+ expect(page).to have_content("Co-author invitation successfully canceled")
+
+ within "#comment_#{comment.id}" do
+ click_on "…"
+ expect(page).to have_link("Mark as co-author")
+ expect(page).to have_no_content("Cancel co-author invitation")
+ end
+
+ expect { notification.reload }.to raise_error(ActiveRecord::RecordNotFound)
+ end
+ end
+ end
+
+ context "when commenter" do
+ let!(:notification) { create(:notification, :proposal_coauthor_invite, user: commenter, resource: proposal) }
+ let(:author_notification) { Decidim::Notification.find_by(user:) }
+
+ before do
+ login_as commenter, scope: :user
+ visit decidim.notifications_path
+ end
+
+ it "coauthor can accept invitation" do
+ expect(page).to have_content("#{user.name} would like to invite you as a co-author of the proposal")
+
+ perform_enqueued_jobs do
+ click_on "Accept"
+
+ expect(page).to have_content("The invitation has been accepted")
+ expect(proposal.reload.authors).to include(commenter)
+ expect { notification.reload }.to raise_error(ActiveRecord::RecordNotFound)
+
+ visit decidim.notifications_path
+ expect(page).to have_no_content("would like to invite you as a co-author of the proposal")
+ expect(page).to have_content("You have been added as a co-author of the proposal")
+ expect(last_email).to be_nil
+ expect(author_notification.event_class).to eq("Decidim::Proposals::CoauthorAcceptedInviteEvent")
+ expect(author_notification.extra["coauthor_id"]).to eq(commenter.id)
+ end
+ end
+
+ it "coauthor can decline invitation" do
+ perform_enqueued_jobs do
+ click_on "Decline"
+
+ expect(page).to have_content("The invitation has been declined")
+ expect(proposal.reload.authors).not_to include(commenter)
+ expect { notification.reload }.to raise_error(ActiveRecord::RecordNotFound)
+
+ visit decidim.notifications_path
+ expect(page).to have_no_content("would like to invite you as a co-author of the proposal")
+ expect(page).to have_content("You have declined the invitation from")
+ expect(last_email).to be_nil
+ expect(author_notification.event_class).to eq("Decidim::Proposals::CoauthorRejectedInviteEvent")
+ expect(author_notification.extra["coauthor_id"]).to eq(commenter.id)
+ end
+ end
+ end
+end
diff --git a/decidim-system/app/cells/decidim/system/system_checks_cell.rb b/decidim-system/app/cells/decidim/system/system_checks_cell.rb
index 658c891248d16..24970a40a9e9c 100644
--- a/decidim-system/app/cells/decidim/system/system_checks_cell.rb
+++ b/decidim-system/app/cells/decidim/system/system_checks_cell.rb
@@ -23,7 +23,7 @@ def checks
end
def correct_secret_key_base?
- Rails.application.secrets.secret_key_base&.length == 128
+ Rails.application.secret_key_base&.length == 128
end
def generated_secret_key
diff --git a/decidim-system/app/forms/decidim/system/base_organization_form.rb b/decidim-system/app/forms/decidim/system/base_organization_form.rb
index f68167899a99c..74c813efcf40f 100644
--- a/decidim-system/app/forms/decidim/system/base_organization_form.rb
+++ b/decidim-system/app/forms/decidim/system/base_organization_form.rb
@@ -114,7 +114,7 @@ def encrypted_omniauth_settings
# We need a valid secret key base for encrypting the SMTP password with it
# It is also necessary for other things in Rails (like Cookies encryption)
def validate_secret_key_base_for_encryption
- return if Rails.application.secrets.secret_key_base&.length == 128
+ return if Rails.application.secret_key_base&.length == 128
errors.add(:password, I18n.t("activemodel.errors.models.organization.attributes.password.secret_key"))
end
diff --git a/decidim-templates/app/controllers/decidim/templates/admin/proposal_answer_templates_controller.rb b/decidim-templates/app/controllers/decidim/templates/admin/proposal_answer_templates_controller.rb
index dab5deae04c4f..adcb945165732 100644
--- a/decidim-templates/app/controllers/decidim/templates/admin/proposal_answer_templates_controller.rb
+++ b/decidim-templates/app/controllers/decidim/templates/admin/proposal_answer_templates_controller.rb
@@ -6,6 +6,7 @@ module Admin
class ProposalAnswerTemplatesController < Decidim::Templates::Admin::ApplicationController
include Decidim::TranslatableAttributes
include Decidim::Paginable
+ include Decidim::Proposals::Admin::NeedsInterpolations
helper_method :availability_option_as_text, :availability_options_for_select, :available_states, :proposal_state
@@ -63,7 +64,7 @@ def fetch
response_object = {
state: state&.token,
- template: populate_template_interpolations(proposal)
+ template: populate_interpolations(template.description, proposal)
}
respond_to do |format|
@@ -138,20 +139,6 @@ def available_states(component_id = nil)
Decidim::Proposals::ProposalState.where(decidim_component_id: component_id)
end
- def populate_template_interpolations(proposal)
- template.description.to_h do |language, value|
- value.gsub!("%{organization}", translated_attribute(proposal.organization.name))
- value.gsub!("%{name}", author_name(proposal))
- value.gsub!("%{admin}", current_user.name)
-
- [language, value]
- end
- end
-
- def author_name(proposal)
- proposal.creator_author.try(:title) || proposal.creator_author.try(:name)
- end
-
def proposal
@proposal ||= Decidim::Proposals::Proposal.find(params[:proposalId])
end
diff --git a/decidim-templates/decidim-templates.gemspec b/decidim-templates/decidim-templates.gemspec
index 061abbcc59154..fdffa26a8d3ba 100644
--- a/decidim-templates/decidim-templates.gemspec
+++ b/decidim-templates/decidim-templates.gemspec
@@ -32,10 +32,10 @@ Gem::Specification.new do |s|
s.add_dependency "decidim-core", Decidim::Templates.version
s.add_dependency "decidim-forms", Decidim::Templates.version
- s.add_dependency "decidim-proposals", Decidim::Templates.version
s.add_development_dependency "decidim-admin", Decidim::Templates.version
s.add_development_dependency "decidim-dev", Decidim::Templates.version
s.add_development_dependency "decidim-participatory_processes", Decidim::Templates.version
+ s.add_development_dependency "decidim-proposals", Decidim::Templates.version
s.add_development_dependency "decidim-surveys", Decidim::Templates.version
end
diff --git a/decidim-templates/lib/decidim/templates/engine.rb b/decidim-templates/lib/decidim/templates/engine.rb
index 52b1f988cc51a..0ea1c044f6632 100644
--- a/decidim-templates/lib/decidim/templates/engine.rb
+++ b/decidim-templates/lib/decidim/templates/engine.rb
@@ -15,10 +15,6 @@ class Engine < ::Rails::Engine
# root to: "templates#index"
end
- initializer "decidim_templates.register_icons" do
- Decidim.icons.register(name: "user-forbid-line", icon: "user-forbid-line", category: "system", description: "", engine: :templates)
- end
-
initializer "decidim_templates.webpacker.assets_path" do
Decidim.register_assets_path File.expand_path("app/packs", root)
end
diff --git a/decidim-templates/spec/system/admin/admin_manages_proposal_bulk_answers_templates_spec.rb b/decidim-templates/spec/system/admin/admin_manages_proposal_bulk_answers_templates_spec.rb
new file mode 100644
index 0000000000000..2b1a4d366491d
--- /dev/null
+++ b/decidim-templates/spec/system/admin/admin_manages_proposal_bulk_answers_templates_spec.rb
@@ -0,0 +1,133 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+describe "Admin manages bulk proposal answer templates" do
+ let(:organization) { create(:organization) }
+ let(:participatory_process) { create(:participatory_process, :with_steps, organization:) }
+ let(:participatory_space) { participatory_process }
+ let!(:component) { create(:proposal_component, participatory_space:) }
+ let(:user) { create(:user, :admin, :confirmed, organization:) }
+ let!(:state) { Decidim::Proposals::ProposalState.first }
+ let!(:proposal) { create(:proposal, cost: nil, component:) }
+ let!(:other_proposals) { create_list(:proposal, 3, component:) }
+ let!(:emendation) { create(:proposal, component:) }
+ let!(:amendment) { create(:amendment, amendable: proposal, emendation:) }
+ let!(:template) { create(:template, target: :proposal_answer, templatable: component, description:, field_values:) }
+ let(:field_values) do
+ { "proposal_state_id" => state.id }
+ end
+ let(:description) do
+ { en: "Hi %{name}, this proposal will be implemented in %{organization}. Signed: %{admin}" }
+ end
+
+ before do
+ switch_to_host(organization.host)
+ login_as user, scope: :user
+ visit manage_component_path(component)
+ # visit current_path
+ page.find(".js-check-all").set(true)
+ click_on "Actions"
+ end
+
+ it "applies the template" do
+ expect(proposal.proposal_state).not_to eq(state)
+ click_on "Apply answer template"
+ expect(page).to have_css("#template_template_id", count: 1)
+ select translated(template.name), from: :template_template_id
+ perform_enqueued_jobs do
+ click_on "Update"
+ end
+
+ expect(page).to have_content("4 proposals will be answered using the template")
+ expect(page).to have_content("Proposals with IDs [#{emendation.id}] could not be answered due errors applying the template")
+ expect(proposal.reload.proposal_state).to eq(state)
+ expect(proposal.answer["en"]).to include("Hi #{proposal.creator_author.name}, this proposal will be implemented in #{organization.name["en"]}. Signed: #{user.name}")
+ other_proposals.each do |reportable|
+ expect(reportable.reload.proposal_state).to eq(state)
+ expect(reportable.answer["en"]).to include("Hi #{reportable.creator_author.name}, this proposal will be implemented in #{organization.name["en"]}. Signed: #{user.name}")
+ end
+ end
+
+ context "when the proposal is official" do
+ let!(:proposal) { create(:proposal, :official, component:) }
+
+ it "applies the template" do
+ expect(proposal.proposal_state).not_to eq(state)
+ click_on "Apply answer template"
+ expect(page).to have_css("#template_template_id", count: 1)
+ select translated(template.name), from: :template_template_id
+ perform_enqueued_jobs do
+ click_on "Update"
+ end
+
+ expect(page).to have_content("4 proposals will be answered using the template")
+ expect(page).to have_content("Proposals with IDs [#{emendation.id}] could not be answered due errors applying the template")
+ expect(proposal.reload.proposal_state).to eq(state)
+ expect(proposal.answer["en"]).to include("Hi #{organization.name["en"]}, this proposal will be implemented in #{organization.name["en"]}. Signed: #{user.name}")
+ end
+ end
+
+ context "when selected proposals are not answerable" do
+ before do
+ page.find(".js-check-all").set(false)
+ page.find(".js-proposal-id-#{emendation.id}").set(true)
+ end
+
+ it "does not apply the template" do
+ expect(page).to have_no_button("Apply answer template")
+ end
+ end
+
+ context "when proposals have costs enabled" do
+ let!(:state) { Decidim::Proposals::ProposalState.find_by(token: "accepted") }
+
+ before do
+ component.update!(
+ step_settings: {
+ component.participatory_space.active_step.id => {
+ answers_with_costs: true
+ }
+ }
+ )
+ end
+
+ it "does not apply the template" do
+ expect(proposal.proposal_state).to be_nil
+ click_on "Apply answer template"
+ expect(page).to have_css("#template_template_id", count: 1)
+ select translated(template.name), from: :template_template_id
+ perform_enqueued_jobs do
+ click_on "Update"
+ end
+
+ expect(page).to have_no_content("proposals will be answered using the template")
+ expect(page).to have_content("could not be answered due errors applying the template")
+ expect(proposal.reload.proposal_state).to be_nil
+ other_proposals.each do |reportable|
+ expect(reportable.reload.proposal_state).to be_nil
+ end
+ end
+ end
+
+ context "when no templates available" do
+ let(:template) { nil }
+
+ it "shows no templates message" do
+ expect(page).to have_no_button("Apply answer template")
+ end
+ end
+
+ context "when templates is not installed" do
+ before do
+ allow(Decidim).to receive(:module_installed?).with(:templates).and_return(false)
+ visit current_path
+ page.find(".js-check-all").set(true)
+ click_on "Actions"
+ end
+
+ it "does not apply the template" do
+ expect(page).to have_no_button("Apply answer template")
+ end
+ end
+end
diff --git a/decidim-verifications/app/forms/decidim/verifications/sms/mobile_phone_form.rb b/decidim-verifications/app/forms/decidim/verifications/sms/mobile_phone_form.rb
index 0bd950ddff831..36054d7b75840 100644
--- a/decidim-verifications/app/forms/decidim/verifications/sms/mobile_phone_form.rb
+++ b/decidim-verifications/app/forms/decidim/verifications/sms/mobile_phone_form.rb
@@ -18,7 +18,7 @@ def handler_name
# A mobile phone can only be verified once but it should be private.
def unique_id
Digest::MD5.hexdigest(
- "#{mobile_phone_number}-#{Rails.application.secrets.secret_key_base}"
+ "#{mobile_phone_number}-#{Rails.application.secret_key_base}"
)
end
diff --git a/decidim-verifications/config/locales/en.yml b/decidim-verifications/config/locales/en.yml
index 12372f0613c25..72fc09724c54b 100644
--- a/decidim-verifications/config/locales/en.yml
+++ b/decidim-verifications/config/locales/en.yml
@@ -44,7 +44,7 @@ en:
destroy:
confirm: Revoke before date authorizations cannot be undone. Are you sure you want to continue?
confirm_all: Revoke all the authorizations cannot be undone. Are you sure you want to continue?
- destroy_nok: There has been a problem while revoking authorizations.
+ destroy_nok: There was a problem while revoking authorizations.
destroy_ok: All matched authorizations have been revocated successfully.
info: There are a total of %{count} verified participants.
no_data: No verified participants.
@@ -158,7 +158,7 @@ en:
admin:
census:
create:
- error: There was an error importing census.
+ error: There was a problem importing census.
success: Successfully imported %{count} items (%{errors} errors).
destroy_all:
success: All census data have been deleted.
diff --git a/decidim.gemspec b/decidim.gemspec
index 4f48c763c3f48..3a1bcbd12f5ca 100644
--- a/decidim.gemspec
+++ b/decidim.gemspec
@@ -63,7 +63,6 @@ Gem::Specification.new do |s|
s.add_dependency "decidim-sortitions", Decidim.version
s.add_dependency "decidim-surveys", Decidim.version
s.add_dependency "decidim-system", Decidim.version
- s.add_dependency "decidim-templates", Decidim.version
s.add_dependency "decidim-verifications", Decidim.version
s.add_development_dependency "bundler", "~> 2.2", ">= 2.2.18"
diff --git a/docs/modules/develop/pages/classes/models.adoc b/docs/modules/develop/pages/classes/models.adoc
index dd248acf9e1da..e631e356f2814 100644
--- a/docs/modules/develop/pages/classes/models.adoc
+++ b/docs/modules/develop/pages/classes/models.adoc
@@ -80,9 +80,9 @@ Most commonly used concerns are:
=== Module specific concerns
-- `Decidim::Comments::Commentable`
-- `Decidim::Comments::CommentableWithComponent`
-- `Decidim::Comments::HasAvailabilityAttributes`
+- `xref:develop:commentable.adoc[Decidim::Comments::Commentable]`
+- `xref:develop:commentable.adoc[Decidim::Comments::CommentableWithComponent]`
+- `xref:develop:commentable.adoc[Decidim::Comments::HasAvailabilityAttributes]`
- `Decidim::Forms::HasQuestionnaire`
- `Decidim::Initiatives::HasArea`
- `Decidim::Initiatives::InitiativeSlug`
diff --git a/docs/modules/develop/pages/commentable.adoc b/docs/modules/develop/pages/commentable.adoc
new file mode 100644
index 0000000000000..f8dd55453df32
--- /dev/null
+++ b/docs/modules/develop/pages/commentable.adoc
@@ -0,0 +1,127 @@
+= Commentable
+
+== Things can be commentable
+
+`Commentable` is a feature to allow participants to comment on resources. This feature is used in many places in Decidim, like proposals, meetings, debates, etc.
+
+When commenting a resource, the comments counter is increased and a notification to all the followers of the participant, the participatory space and/or the resource is sent.
+
+Participants can comment with their own identity or with the identify of the `user_groups` they belong to.
+
+== Data model
+
+The `decidim_comments` table stores all the comments given to resources that are commentable. This is, one commentable has many comments, and each comment belongs to one commentable. Also, a comment can be a commentable itself, so comments can be nested.
+For performance, a commentable has a counter cache of comments.
+
+[source,ascii]
+----
++----------------------+
+| Decidim::Commentable |
+| ((Proposal,...)) | +-------------+
++----------------------+ 0..N +-------------------+ +--+Decidim::User|
+|-has_many comments |-------+Decidim::Comment | | +-------------+
+|#counter cache column | +-------------------+ |
+|-comments_counter | |-author: may be a |<--+
++----------------------+ | user or a | |
+ | user_group| | +------------------+
+ +-------------------+ +--+Decidim::UserGroup|
+ +------------------+
+----
+
+Thus, each commentable must have the comments counter cache column.
+This is an example migration to add the comments counter cache column to a resource:
+
+[source,ruby]
+----
+class AddCommentableCounterCacheToMeetings < ActiveRecord::Migration[5.2]
+ def change
+ add_column :decidim_meetings_meetings, :comments_count, :integer, null: false, default: 0
+ Decidim::Meetings::Meeting.reset_column_information
+ Decidim::Meetings::Meeting.find_each(&:update_comments_count)
+ end
+end
+----
+
+== Public view
+
+=== The "Comment" cell
+
+The `Comment` cell is used to render a comment in the public view. Usually, it is used in the `Comments` cell to render a list of comments.
+
+[source,ruby]
+----
+cell("decidim/comments", resource)
+----
+
+This will render all the comments for the given resource.
+
+=== Comments actions
+
+Each comment has a set of actions that can be performed by the user. By default, these actions are available:
+
+- A user can edit and delete their own comments.
+- A user can report a comment.
+- A user can copy the link to a comment.
+
+These actions are available through a dropdown menu in the comment.
+
+=== Resource-specific extra actions
+
+Each resource can define extra actions that can be performed on comments. These actions must be returned by the resource object through the `actions_for_comment` method. If the resource does not define this method, or returns empty, no extra actions will be available.
+
+This method will receive two parameters, the comment itself and the current user that wants to interact with the comment.
+
+It must return an array of hashes, where each hash has the following keys:
+
+- `label`: The text for the link for the action.
+- `url`: The URL where the action will be performed.
+- `icon`: The icon to be displayed for the action (optional).
+- `method`: The HTTP method for the action, usually `:post` or `:delete` (optional as it defaults to `get`).
+- `data`: A hash with the data attributes for the link (optional).
+
+All these extra actions will be displayed in the dropdown menu of the comment after the default ones.
+
+For example, this is how the `Proposal` model defines extra actions for comments:
+
+[source,ruby]
+----
+def user_has_actions?(user)
+ return false if authors.include?(user)
+ return false if user&.blocked?
+ return false if user&.deleted?
+ return false unless user&.confirmed?
+
+ true
+end
+
+def actions_for_comment(comment, current_user)
+ return if comment.commentable != self
+ return unless authors.include?(current_user)
+ return unless user_has_actions?(comment.author)
+
+ if coauthor_invitations_for(comment.author).any?
+ [
+ {
+ label: I18n.t("decidim.proposals.actions.cancel_coauthor_invitation"),
+ url: EngineRouter.main_proxy(component).cancel_proposal_invite_coauthors_path(proposal_id: id, id: comment.author.id),
+ icon: "user-forbid-line",
+ method: :delete,
+ data: { confirm: I18n.t("decidim.proposals.actions.cancel_coauthor_invitation_confirm") }
+ }
+ ]
+ else
+ [
+ {
+ label: I18n.t("decidim.proposals.actions.mark_as_coauthor"),
+ url: EngineRouter.main_proxy(component).proposal_invite_coauthors_path(proposal_id: id, id: comment.author.id),
+ icon: "user-add-line",
+ method: :post,
+ data: { confirm: I18n.t("decidim.proposals.actions.mark_as_coauthor_confirm") }
+ }
+ ]
+ end
+end
+----
+
+This will render a new menu item with the text "Mark as coauthor" or "Cancel coauthor invitation" depending on the state of the comment author that will allow to add the comment's author as a co-author of the proposal.
+
diff --git a/docs/modules/services/pages/maps.adoc b/docs/modules/services/pages/maps.adoc
index 27350b3f532a5..64bacc24ca66a 100644
--- a/docs/modules/services/pages/maps.adoc
+++ b/docs/modules/services/pages/maps.adoc
@@ -241,8 +241,8 @@ As of April 2017, only proposals and meetings have maps and geocoding.
=== Proposals
-In order to enable geocoding for proposals you will need to edit the component configuration and turn on "Geocoding enabled" configuration.
-This works for that specific component, so you can have geocoding enabled for proposals in a participatory process, and disabled for another proposals component in the same participatory process.
+In order to enable maps for proposals you will need to edit the component configuration and turn on "Maps enabled" configuration.
+This works for that specific component, so you can have maps enabled for proposals in a participatory process, and disabled for another proposals component in the same participatory process.
=== Meetings
diff --git a/lib/decidim/gem_manager.rb b/lib/decidim/gem_manager.rb
index 30ad364b33f45..4283d28b1d076 100644
--- a/lib/decidim/gem_manager.rb
+++ b/lib/decidim/gem_manager.rb
@@ -223,8 +223,6 @@ def patch_component_gemfile_generator
gem "faker", "#{Gem.loaded_specs["decidim-dev"].dependencies.select { |a| a.name == "faker" }.first.requirement}"
gem "letter_opener_web", "#{fetch_gemfile_version("letter_opener_web")}"
gem "listen", "#{fetch_gemfile_version("listen")}"
- gem "spring", "#{fetch_gemfile_version("spring")}"
- gem "spring-watcher-listen", "#{fetch_gemfile_version("spring-watcher-listen")}"
gem "web-console", "#{fetch_gemfile_version("web-console")}"
end
)