decidim-meetings 0.5.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/config/admin/decidim_meetings_manifest.js +1 -0
  3. data/app/assets/images/decidim/meetings/icon.svg +5 -1
  4. data/app/assets/javascripts/decidim/meetings/admin/registrations_form.js.es6 +21 -0
  5. data/app/commands/decidim/meetings/admin/close_meeting.rb +17 -9
  6. data/app/commands/decidim/meetings/admin/create_meeting.rb +13 -1
  7. data/app/commands/decidim/meetings/admin/update_meeting.rb +47 -21
  8. data/app/commands/decidim/meetings/admin/update_registrations.rb +60 -0
  9. data/app/commands/decidim/meetings/join_meeting.rb +73 -0
  10. data/app/commands/decidim/meetings/leave_meeting.rb +39 -0
  11. data/app/controllers/decidim/meetings/admin/registrations_controller.rb +43 -0
  12. data/app/controllers/decidim/meetings/registrations_controller.rb +46 -0
  13. data/app/events/decidim/meetings/close_meeting_event.rb +30 -0
  14. data/app/events/decidim/meetings/meeting_registrations_enabled_event.rb +39 -0
  15. data/app/events/decidim/meetings/meeting_registrations_over_percentage_event.rb +43 -0
  16. data/app/events/decidim/meetings/upcoming_meeting_event.rb +30 -0
  17. data/app/events/decidim/meetings/update_meeting_event.rb +30 -0
  18. data/app/forms/decidim/meetings/admin/meeting_form.rb +1 -1
  19. data/app/forms/decidim/meetings/admin/meeting_registrations_form.rb +32 -0
  20. data/app/helpers/decidim/meetings/application_helper.rb +1 -0
  21. data/app/jobs/decidim/meetings/upcoming_meeting_notification_job.rb +33 -0
  22. data/app/mailers/decidim/meetings/registration_mailer.rb +46 -0
  23. data/app/models/decidim/meetings/abilities/current_user_ability.rb +43 -0
  24. data/app/models/decidim/meetings/meeting.rb +42 -0
  25. data/app/models/decidim/meetings/registration.rb +13 -0
  26. data/app/serializers/decidim/meetings/registration_serializer.rb +18 -0
  27. data/app/views/decidim/meetings/admin/meetings/_form.html.erb +3 -3
  28. data/app/views/decidim/meetings/admin/meetings/index.html.erb +1 -0
  29. data/app/views/decidim/meetings/admin/registrations/_form.html.erb +33 -0
  30. data/app/views/decidim/meetings/admin/registrations/edit.html.erb +8 -0
  31. data/app/views/decidim/meetings/meetings/_filters.html.erb +2 -2
  32. data/app/views/decidim/meetings/meetings/_registration_confirm.html.erb +15 -0
  33. data/app/views/decidim/meetings/meetings/show.html.erb +15 -1
  34. data/app/views/decidim/meetings/registration_mailer/confirmation.html.erb +3 -0
  35. data/config/locales/ca.yml +74 -0
  36. data/config/locales/en.yml +72 -4
  37. data/config/locales/es.yml +75 -1
  38. data/config/locales/eu.yml +78 -3
  39. data/config/locales/fi.yml +84 -0
  40. data/config/locales/fr.yml +83 -8
  41. data/config/locales/it.yml +87 -0
  42. data/config/locales/nl.yml +169 -0
  43. data/config/locales/pl.yml +113 -0
  44. data/config/locales/uk.yml +178 -0
  45. data/db/migrate/20170810120836_add_registration_attributes_to_meetings.rb +9 -0
  46. data/db/migrate/20170810131100_create_registrations.rb +14 -0
  47. data/lib/decidim/meetings/admin_engine.rb +9 -0
  48. data/lib/decidim/meetings/engine.rb +8 -0
  49. data/lib/decidim/meetings/feature.rb +39 -9
  50. data/lib/decidim/meetings/test/factories.rb +11 -0
  51. metadata +65 -13
  52. data/config/i18n-tasks.yml +0 -10
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Meetings
5
+ module Admin
6
+ # This class holds a Form to update meeting registrations from Decidim's admin panel.
7
+ class MeetingRegistrationsForm < Decidim::Form
8
+ include TranslatableAttributes
9
+
10
+ mimic :meeting
11
+
12
+ attribute :registrations_enabled, Boolean
13
+ attribute :available_slots, Integer
14
+ translatable_attribute :registration_terms, String
15
+
16
+ validates :registration_terms, translatable_presence: true, if: ->(form) { form.registrations_enabled? }
17
+ validates :available_slots, numericality: { greater_than_or_equal_to: 0 }, if: ->(form) { form.registrations_enabled? }
18
+ validate :available_slots_greater_than_or_equal_to_registrations_count, if: ->(form) { form.registrations_enabled? && form.available_slots.positive? }
19
+
20
+ private
21
+
22
+ def available_slots_greater_than_or_equal_to_registrations_count
23
+ errors.add(:available_slots, :invalid) if available_slots < meeting.registrations.count
24
+ end
25
+
26
+ def meeting
27
+ @meeting ||= context[:meeting]
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -9,6 +9,7 @@ module Decidim
9
9
  include Decidim::MapHelper
10
10
  include Decidim::Meetings::MapHelper
11
11
  include Decidim::Meetings::MeetingsHelper
12
+ include Decidim::Comments::CommentsHelper
12
13
  end
13
14
  end
14
15
  end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Meetings
5
+ class UpcomingMeetingNotificationJob < ApplicationJob
6
+ queue_as :decidim_events
7
+
8
+ def perform(meeting_id, checksum)
9
+ meeting = Decidim::Meetings::Meeting.find(meeting_id)
10
+ send_notification(meeting) if verify_checksum(meeting, checksum)
11
+ end
12
+
13
+ def self.generate_checksum(meeting)
14
+ Digest::MD5.hexdigest("#{meeting.id}-#{meeting.start_time}")
15
+ end
16
+
17
+ private
18
+
19
+ def send_notification(meeting)
20
+ Decidim::EventsManager.publish(
21
+ event: "decidim.events.meetings.upcoming_meeting",
22
+ event_class: Decidim::Meetings::UpcomingMeetingEvent,
23
+ resource: meeting,
24
+ recipient_ids: meeting.followers.pluck(:id)
25
+ )
26
+ end
27
+
28
+ def verify_checksum(meeting, checksum)
29
+ self.class.generate_checksum(meeting) == checksum
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Meetings
5
+ # A custom mailer for sending notifications to users when
6
+ # they join a meeting.
7
+ class RegistrationMailer < Decidim::ApplicationMailer
8
+ include Decidim::TranslationsHelper
9
+ include ActionView::Helpers::SanitizeHelper
10
+
11
+ helper Decidim::ResourceHelper
12
+ helper Decidim::TranslationsHelper
13
+
14
+ def confirmation(user, meeting)
15
+ with_user(user) do
16
+ @user = user
17
+ @meeting = meeting
18
+ @organization = @meeting.organization
19
+ @locator = Decidim::ResourceLocatorPresenter.new(@meeting)
20
+
21
+ add_calendar_attachment
22
+
23
+ subject = I18n.t("confirmation.subject", scope: "decidim.meetings.mailer.registration_mailer")
24
+ mail(to: user.email, subject: subject)
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def add_calendar_attachment
31
+ calendar = Icalendar::Calendar.new
32
+ calendar.event do |event|
33
+ event.dtstart = Icalendar::Values::DateTime.new(@meeting.start_time)
34
+ event.dtend = Icalendar::Values::DateTime.new(@meeting.end_time)
35
+ event.summary = translated_attribute @meeting.title
36
+ event.description = strip_tags(translated_attribute(@meeting.description))
37
+ event.location = @meeting.address
38
+ event.geo = [@meeting.latitude, @meeting.longitude]
39
+ event.url = @locator.url
40
+ end
41
+
42
+ attachments["meeting-calendar-info.ics"] = calendar.to_ical
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Meetings
5
+ module Abilities
6
+ # Defines the abilities related to meetings for a logged in user.
7
+ # Intended to be used with `cancancan`.
8
+ class CurrentUserAbility
9
+ include CanCan::Ability
10
+
11
+ attr_reader :user, :context
12
+
13
+ def initialize(user, context)
14
+ return unless user
15
+
16
+ @user = user
17
+ @context = context
18
+
19
+ can :join, Meeting do |meeting|
20
+ authorized?(:join) && meeting.registrations_enabled?
21
+ end
22
+
23
+ can :leave, Meeting, &:registrations_enabled?
24
+ end
25
+
26
+ private
27
+
28
+ def authorized?(action)
29
+ return unless feature
30
+
31
+ ActionAuthorizer.new(user, feature, action).authorize.ok?
32
+ end
33
+
34
+ def feature
35
+ feature = context.fetch(:current_feature, nil)
36
+ return nil unless feature && feature.manifest.name == :meetings
37
+
38
+ feature
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -11,6 +11,10 @@ module Decidim
11
11
  include Decidim::HasReference
12
12
  include Decidim::HasScope
13
13
  include Decidim::HasCategory
14
+ include Decidim::Followable
15
+ include Decidim::Comments::Commentable
16
+
17
+ has_many :registrations, class_name: "Decidim::Meetings::Registration", foreign_key: "decidim_meeting_id"
14
18
 
15
19
  feature_manifest_name "meetings"
16
20
 
@@ -21,6 +25,44 @@ module Decidim
21
25
  def closed?
22
26
  closed_at.present?
23
27
  end
28
+
29
+ def has_available_slots?
30
+ return true if available_slots.zero?
31
+ available_slots > registrations.count
32
+ end
33
+
34
+ def remaining_slots
35
+ available_slots - registrations.count
36
+ end
37
+
38
+ def has_registration_for?(user)
39
+ registrations.where(user: user).any?
40
+ end
41
+
42
+ # Public: Overrides the `commentable?` Commentable concern method.
43
+ def commentable?
44
+ feature.settings.comments_enabled?
45
+ end
46
+
47
+ # Public: Overrides the `accepts_new_comments?` Commentable concern method.
48
+ def accepts_new_comments?
49
+ commentable? && !feature.current_settings.comments_blocked
50
+ end
51
+
52
+ # Public: Overrides the `comments_have_alignment?` Commentable concern method.
53
+ def comments_have_alignment?
54
+ true
55
+ end
56
+
57
+ # Public: Overrides the `comments_have_votes?` Commentable concern method.
58
+ def comments_have_votes?
59
+ true
60
+ end
61
+
62
+ # Public: Override Commentable concern method `users_to_notify_on_comment_created`
63
+ def users_to_notify_on_comment_created
64
+ followers
65
+ end
24
66
  end
25
67
  end
26
68
  end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Meetings
5
+ # The data store for a Registration in the Decidim::Meetings component.
6
+ class Registration < Meetings::ApplicationRecord
7
+ belongs_to :meeting, foreign_key: "decidim_meeting_id", class_name: "Decidim::Meetings::Meeting"
8
+ belongs_to :user, foreign_key: "decidim_user_id", class_name: "Decidim::User"
9
+
10
+ validates :user, uniqueness: { scope: :meeting }
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Meetings
5
+ class RegistrationSerializer < Decidim::Exporters::Serializer
6
+ # Serializes a registration
7
+ def serialize
8
+ {
9
+ id: resource.id,
10
+ user: {
11
+ name: resource.user.name,
12
+ email: resource.user.email
13
+ }
14
+ }
15
+ end
16
+ end
17
+ end
18
+ end
@@ -34,14 +34,14 @@
34
34
  </div>
35
35
  </div>
36
36
  <div class="row" >
37
- <% if current_participatory_process.has_subscopes? %>
37
+ <% if current_participatory_space.has_subscopes? %>
38
38
  <div class="columns xlarge-6" >
39
- <%= form.scopes_select :decidim_scope_id, prompt: I18n.t("decidim.scopes.global"), remote_path: decidim.scopes_search_path(root: current_participatory_process.scope) %>
39
+ <%= form.scopes_select :decidim_scope_id, prompt: I18n.t("decidim.scopes.global"), remote_path: decidim.scopes_search_path(root: current_participatory_space.scope) %>
40
40
  </div>
41
41
  <% end %>
42
42
 
43
43
  <div class="columns xlarge-6" >
44
- <%= form.categories_select :decidim_category_id, current_participatory_process.categories, prompt: "", disable_parents: false %>
44
+ <%= form.categories_select :decidim_category_id, current_participatory_space.categories, prompt: "", disable_parents: false %>
45
45
  </div>
46
46
  </div>
47
47
  </div>
@@ -50,6 +50,7 @@
50
50
 
51
51
  <% if can? :update, current_feature %>
52
52
  <%= icon_link_to "pencil", edit_meeting_path(meeting), t("actions.edit", scope: "decidim.meetings"), class: "action-icon--edit" %>
53
+ <%= icon_link_to "people", edit_meeting_registrations_path(meeting), t("actions.registrations", scope: "decidim.meetings"), class: "action-icon--registrations" %>
53
54
  <% end %>
54
55
 
55
56
  <% if can? :update, current_feature %>
@@ -0,0 +1,33 @@
1
+ <div class="card">
2
+ <div class="card-divider">
3
+ <h2 class="card-title">
4
+ <%= title %>
5
+ <span class="exports dropdown tiny button button--simple button--title" data-toggle="export-dropdown"><%= t "actions.export", scope: "decidim.admin" %></span>
6
+ <div class="dropdown-pane" id="export-dropdown" data-dropdown data-auto-focus="true" data-close-on-click="true">
7
+ <ul class="vertical menu add-features">
8
+ <% %w{csv json}.each do |format| %>
9
+ <li class="exports--format--<%= format %> exports--registrations"><%= link_to t("decidim.admin.exports.export_as", name: t("decidim.#{current_feature.manifest.name}.admin.exports.registrations"), export_format: format.upcase), export_meeting_registrations_path(meeting_id: meeting, format: format) %></li>
10
+ <% end %>
11
+ </ul>
12
+ </div>
13
+ </h2>
14
+ </div>
15
+
16
+ <div class="card-section">
17
+ <div class="row column">
18
+ <%= form.check_box :registrations_enabled %>
19
+ </div>
20
+
21
+ <div class="row column">
22
+ <p><%= t(".registrations_count", count: meeting.registrations.count) %></p>
23
+ <%= form.number_field :available_slots %>
24
+ <p class="help-text"><%= t(".available_slots_help") %></p>
25
+ </div>
26
+
27
+ <div class="row column">
28
+ <%= form.translated :editor, :registration_terms %>
29
+ </div>
30
+ </div>
31
+ </div>
32
+
33
+ <%= javascript_include_tag "decidim/meetings/admin/registrations_form" %>
@@ -0,0 +1,8 @@
1
+ <%= decidim_form_for(@form, url: meeting_registrations_path, html: { class: "form edit_meeting_registrations" }) do |f| %>
2
+ <%= render partial: 'form', object: f %>
3
+
4
+ <div class="button--double form-general-submit">
5
+ <%= f.submit t(".save") %>
6
+ </div>
7
+ <% end %>
8
+
@@ -16,8 +16,8 @@
16
16
  <%= form.collection_radio_buttons :date, [["upcoming", t(".upcoming")], ["past", t(".past")]], :first, :last, legend_title: t(".date") %>
17
17
  <% end %>
18
18
 
19
- <% if current_participatory_process.has_subscopes? %>
20
- <%= form.scopes_select :scope_id, legend_title: t(".scopes"), label: false, prompt: t('.scope_prompt'), remote_path: decidim.scopes_search_path(root: current_participatory_process.scope, include_root: true), multiple: true %>
19
+ <% if current_participatory_space.has_subscopes? %>
20
+ <%= form.scopes_select :scope_id, legend_title: t(".scopes"), label: false, prompt: t('.scope_prompt'), remote_path: decidim.scopes_search_path(root: current_participatory_space.scope, include_root: true), multiple: true %>
21
21
  <% end %>
22
22
 
23
23
  <% if current_feature.categories.any? %>
@@ -0,0 +1,15 @@
1
+ <div class="reveal" data-reveal id="meeting-registration-confirm">
2
+ <div class="row">
3
+ <div class="columns medium-10 medium-offset-1 help-text">
4
+ <%== translated_attribute(meeting.registration_terms) %>
5
+ </div>
6
+ </div>
7
+ <div class="row">
8
+ <div class="columns medium-8 medium-offset-2">
9
+ <%= button_to t('.confirm'), meeting_registration_path(meeting), class: "button expanded" %>
10
+ </div>
11
+ </div>
12
+ <div class="text-center">
13
+ <button class="link" data-close><%= t('.cancel') %></button>
14
+ </div>
15
+ </div>
@@ -20,7 +20,17 @@
20
20
  <div class="extra__time">
21
21
  <%= meeting.start_time.strftime("%H:%M") %> - <%= meeting.end_time.strftime("%H:%M") %>
22
22
  </div>
23
- </div>
23
+ <% if !meeting.closed? && meeting.registrations_enabled? %>
24
+ <% if meeting.has_registration_for? current_user %>
25
+ <%= action_authorized_button_to :leave, t('.going'), meeting_registration_path(meeting), method: :delete, class: "button expanded button--sc success" %>
26
+ <% else %>
27
+ <%= action_authorized_button_to :join, meeting.has_available_slots? ? t('.join') : t('.no_slots_available'), "", class: "button expanded button--sc", disabled: !meeting.has_available_slots?, data: { toggle: current_user.present? ? "meeting-registration-confirm" : "loginModal" } %>
28
+ <% end %>
29
+ <% if meeting.available_slots.positive? %>
30
+ <span><%= t(".remaining_slots", count: meeting.remaining_slots) %></span>
31
+ <% end %>
32
+ <% end %>
33
+ <%= render partial: "decidim/shared/follow_button", locals: { followable: meeting } %>
24
34
  </div>
25
35
  <% if meeting.closed? %>
26
36
  <div class="card card--secondary extra definition-data">
@@ -45,6 +55,7 @@
45
55
  </div>
46
56
  </div>
47
57
  <% end %>
58
+ </div>
48
59
  <%= feature_reference(meeting) %>
49
60
  <%= render partial: "decidim/shared/share_modal" %>
50
61
  <%= embed_modal_for meeting_meeting_widget_url(meeting, format: :js) %>
@@ -66,6 +77,9 @@
66
77
  </div>
67
78
  </div>
68
79
  <%= attachments_for meeting %>
80
+ <%= comments_for meeting %>
81
+
82
+ <%= render partial: "registration_confirm" %>
69
83
 
70
84
  <%= javascript_include_tag "decidim/proposals/social_share" %>
71
85
  <%= stylesheet_link_tag "decidim/proposals/social_share" %>
@@ -0,0 +1,3 @@
1
+ <p><%= t(".confirmed_html", title: translated_attribute(@meeting.title), url: @locator.url) %></p>
2
+
3
+ <p><%= t(".details") %></p>
@@ -1,3 +1,4 @@
1
+ ---
1
2
  ca:
2
3
  activemodel:
3
4
  attributes:
@@ -20,7 +21,16 @@ ca:
20
21
  decidim:
21
22
  features:
22
23
  meetings:
24
+ actions:
25
+ join: Inscriu-t'hi
23
26
  name: Trobades
27
+ settings:
28
+ global:
29
+ announcement: Avís
30
+ comments_enabled: Comentaris habilitats
31
+ step:
32
+ announcement: Avís
33
+ comments_blocked: Comentaris bloquejats
24
34
  meetings:
25
35
  actions:
26
36
  attachments: Adjunts
@@ -30,8 +40,11 @@ ca:
30
40
  edit: Edita
31
41
  new: Nova
32
42
  preview: Previsualitzar
43
+ registrations: Inscripcions
33
44
  title: Accions
34
45
  admin:
46
+ exports:
47
+ registrations: Inscripcions
35
48
  meeting_closes:
36
49
  edit:
37
50
  close: Tancar
@@ -58,6 +71,47 @@ ca:
58
71
  models:
59
72
  meeting:
60
73
  name: Trobada
74
+ registrations:
75
+ edit:
76
+ save: Desa
77
+ form:
78
+ available_slots_help: Deixeu-lo a 0 si teniu espais il·limitats disponibles.
79
+ registrations_count:
80
+ one: Hi ha hagut 1 inscripció.
81
+ other: Hi ha hagut %{count} inscripcions.
82
+ update:
83
+ invalid: S'ha produït un problema en desar la configuració de la inscripció.
84
+ success: La configuració de les inscripcions de la trobada s'ha desat correctament.
85
+ events:
86
+ close_meeting_event:
87
+ email_intro: 'La trobada de "%{resource_title}" ha estat tancada. Podeu llegir les conclusions a la seva pàgina:'
88
+ email_outro: Has rebut aquesta notificació, perquè estàs seguint la trobada "%{resource_title}". Pots deixar-la de seguir des del seu enllaç.
89
+ email_subject: S'ha tancat la trobada "%{resource_title}"
90
+ notification_title: La trobada de <a href="%{resource_path}">%{resource_title}</a> s'ha tancat.
91
+ meeting_registrations_enabled:
92
+ email_intro: 'La trobada "%{resource_title}" ha activat inscripcions. Pots registrar-te a la seva pàgina:'
93
+ email_outro: Has rebut aquesta notificació perquè estàs seguint la trobada "%{resource_title}". Pots deixar-la de seguir a l'enllaç anterior.
94
+ email_subject: La trobada de "%{resource_title}" ha permès inscripcions.
95
+ notification_title: La trobada <a href="%{resource_path}">%{resource_title}</a> ha activat inscripcions.
96
+ meeting_registrations_over_percentage:
97
+ email_intro: La disponibilitat d'espais a la trobada "%{resource_title}" està per sobre del %{percentage}%.
98
+ email_outro: Has rebut aquesta notificació perquè ets un administrador de l'espai participatiu d'aquesta trobada.
99
+ email_subject: L'espai ocupat per la trobada "%{resource_title}" està per sobre del %{percentage}%
100
+ notification_title: L'espai ocupat per la trobada <a href="%{resource_path}">%{resource_title}</a> està per sobre del %{percentage}%.
101
+ upcoming_meeting_event:
102
+ email_intro: En menys de 48 hores s'iniciarà la trobada "%{resource_title}".
103
+ email_outro: Has rebut aquesta notificació perquè estàs seguint la trobada "%{resource_title}". Pots deixar-la de seguir a l'enllaç anterior.
104
+ email_subject: En menys de 48 hores s'iniciarà la trobada "%{resource_title}".
105
+ notification_title: La trobada <a href="%{resource_path}">%{resource_title}</a> començarà en menys de 48 hores.
106
+ update_meeting_event:
107
+ email_intro: 'La trobada de "%{resource_title}" ha estat actualitzada. Pots llegir-ne la nova versió a la seva pàgina:'
108
+ email_outro: Has rebut aquesta notificació perquè estàs seguint la trobada "%{resource_title}". Pots deixar-la de seguir des de l'enllaç anterior.
109
+ email_subject: La trobada "%{resource_title}" s'ha actualitzat
110
+ notification_title: La trobada <a href="%{resource_path}">%{resource_title}</a> ha estat actualitzada.
111
+ mailer:
112
+ registration_mailer:
113
+ confirmation:
114
+ subject: La teva inscripció a la trobada ha estat confirmada
61
115
  meetings:
62
116
  filters:
63
117
  category: Categoria
@@ -78,11 +132,20 @@ ca:
78
132
  meetings:
79
133
  no_meetings_warning: No hi ha trobades que coincideixin amb el criteri de cerca o no hi ha cap trobada programada.
80
134
  upcoming_meetings_warning: Actualment no hi ha trobades programades, però pots veure les anteriors trobades.
135
+ registration_confirm:
136
+ cancel: Cancel·lar
137
+ confirm: Confirmar
81
138
  show:
82
139
  attendees: Nombre d'assistents
83
140
  contributions: Nombre d'aportacions
141
+ going: Inscrit
142
+ join: Inscriu-te a la reunió
84
143
  meeting_report: Informe de la trobada
144
+ no_slots_available: No hi ha lloc disponible
85
145
  organizations: Llista d'organitzacions que han atès
146
+ remaining_slots:
147
+ one: 1 espai reservat restant
148
+ other: "%{count} inscripcions restants"
86
149
  models:
87
150
  meeting:
88
151
  fields:
@@ -92,6 +155,17 @@ ca:
92
155
  start_time: Data d'inici
93
156
  title: Títol
94
157
  read_more: "(Llegeix més)"
158
+ registration_mailer:
159
+ confirmation:
160
+ confirmed_html: La teva inscripció a la trobada <a href="%{url}">%{title}</a> ha estat confirmada.
161
+ details: A l'arxiu adjunt trobaràs els detalls de la reunió.
162
+ registrations:
163
+ create:
164
+ invalid: Hi ha hagut un problema en inscriure's a aquesta reunió.
165
+ success: T'has inscrit a la reunió amb èxit.
166
+ destroy:
167
+ invalid: Hi ha hagut un problema en sortir d'aquesta trobada.
168
+ success: Heu deixat la trobada amb èxit.
95
169
  resource_links:
96
170
  meetings_through_proposals:
97
171
  meeting_results: 'Resultats relacionats:'
@@ -21,12 +21,16 @@ en:
21
21
  decidim:
22
22
  features:
23
23
  meetings:
24
+ actions:
25
+ join: Join
24
26
  name: Meetings
25
27
  settings:
26
28
  global:
27
29
  announcement: Announcement
30
+ comments_enabled: Comments enabled
28
31
  step:
29
32
  announcement: Announcement
33
+ comments_blocked: Comments blocked
30
34
  meetings:
31
35
  actions:
32
36
  attachments: Attachments
@@ -36,8 +40,11 @@ en:
36
40
  edit: Edit
37
41
  new: New
38
42
  preview: Preview
43
+ registrations: Registrations
39
44
  title: Actions
40
45
  admin:
46
+ exports:
47
+ registrations: Registrations
41
48
  meeting_closes:
42
49
  edit:
43
50
  close: Close
@@ -64,6 +71,48 @@ en:
64
71
  models:
65
72
  meeting:
66
73
  name: Meeting
74
+ registrations:
75
+ edit:
76
+ save: Save
77
+ form:
78
+ available_slots_help: Leave it to 0 if you have unlimited slots available.
79
+ registrations_count:
80
+ one: There has been 1 registration.
81
+ other: There has been %{count} registrations.
82
+ zero: There has not been registrations yet.
83
+ update:
84
+ invalid: There's been a problem saving the registration settings.
85
+ success: Meeting registrations settings successfully saved.
86
+ events:
87
+ close_meeting_event:
88
+ email_intro: 'The "%{resource_title}" meeting was closed. You can read the conclusions from its page:'
89
+ email_outro: You have received this notification because you are following the "%{resource_title}" meeting. You can unfollow it from the previous link.
90
+ email_subject: The "%{resource_title}" meeting was closed
91
+ notification_title: The <a href="%{resource_path}">%{resource_title}</a> meeting was closed.
92
+ meeting_registrations_enabled:
93
+ email_intro: 'The "%{resource_title}" meeting has enabled registrations. You can register yourself on its page:'
94
+ email_outro: You have received this notification because you are following the "%{resource_title}" meeting. You can unfollow it from the previous link.
95
+ email_subject: The "%{resource_title}" meeting has enabled registrations.
96
+ notification_title: The <a href="%{resource_path}">%{resource_title}</a> meeting has enabled registrations.
97
+ meeting_registrations_over_percentage:
98
+ email_intro: The "%{resource_title}" meeting occupied slots are over %{percentage}%.
99
+ email_outro: You have received this notification because you are an admin of the meeting's participatory space.
100
+ email_subject: The "%{resource_title}" meeting occupied slots are over %{percentage}%
101
+ notification_title: The <a href="%{resource_path}">%{resource_title}</a> meeting occupied slots are over %{percentage}%.
102
+ upcoming_meeting_event:
103
+ email_intro: The "%{resource_title}" meeting will start in less than 48h.
104
+ email_outro: You have received this notification because you are following the "%{resource_title}" meeting. You can unfollow it from the previous link.
105
+ email_subject: The "%{resource_title}" meeting will start in less than 48h.
106
+ notification_title: The <a href="%{resource_path}">%{resource_title}</a> meeting will start in less than 48h.
107
+ update_meeting_event:
108
+ email_intro: 'The "%{resource_title}" meeting was updated. You can read the new version from its page:'
109
+ email_outro: You have received this notification because you are following the "%{resource_title}" meeting. You can unfollow it from the previous link.
110
+ email_subject: The "%{resource_title}" meeting was updated
111
+ notification_title: The <a href="%{resource_path}">%{resource_title}</a> meeting was updated.
112
+ mailer:
113
+ registration_mailer:
114
+ confirmation:
115
+ subject: Your meeting's registration has been confirmed
67
116
  meetings:
68
117
  filters:
69
118
  category: Category
@@ -82,15 +131,23 @@ en:
82
131
  index:
83
132
  view_meeting: View meeting
84
133
  meetings:
85
- no_meetings_warning: No meetings match your search criteria or there isn't
86
- any meeting scheduled.
87
- upcoming_meetings_warning: Currently, there are no scheduled meetings, but
88
- here you can find all the past meetings listed.
134
+ no_meetings_warning: No meetings match your search criteria or there isn't any meeting scheduled.
135
+ upcoming_meetings_warning: Currently, there are no scheduled meetings, but here you can find all the past meetings listed.
136
+ registration_confirm:
137
+ cancel: Cancel
138
+ confirm: Confirm
89
139
  show:
90
140
  attendees: Attendees count
91
141
  contributions: Contributions count
142
+ going: Going
143
+ join: Join meeting
92
144
  meeting_report: Meeting report
145
+ no_slots_available: No slots available
93
146
  organizations: Attending organizations
147
+ remaining_slots:
148
+ one: 1 slot remaining
149
+ other: "%{count} slots remaining"
150
+ zero: No slots remaining
94
151
  models:
95
152
  meeting:
96
153
  fields:
@@ -100,6 +157,17 @@ en:
100
157
  start_time: Start date
101
158
  title: Title
102
159
  read_more: "(read more)"
160
+ registration_mailer:
161
+ confirmation:
162
+ confirmed_html: Your registration for the meeting <a href="%{url}">%{title}</a> has been confirmed.
163
+ details: You will find the meeting's details in the attachment.
164
+ registrations:
165
+ create:
166
+ invalid: There's been a problem joining this meeting.
167
+ success: You have joined the meeting successfully.
168
+ destroy:
169
+ invalid: There's been a problem leaving this meeting.
170
+ success: You have left the meeting successfully.
103
171
  resource_links:
104
172
  meetings_through_proposals:
105
173
  meeting_results: 'Related results:'