decidim-core 0.12.2 → 0.13.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/stylesheets/decidim/modules/_order-by.scss +4 -1
  3. data/app/cells/decidim/author/comments.erb +2 -2
  4. data/app/cells/decidim/author/date.erb +1 -1
  5. data/app/cells/decidim/author_cell.rb +22 -38
  6. data/app/cells/decidim/card_m/authors.erb +9 -0
  7. data/app/cells/decidim/card_m/status.erb +1 -1
  8. data/app/cells/decidim/card_m_cell.rb +8 -0
  9. data/app/cells/decidim/collapsible_authors/show.erb +16 -0
  10. data/app/cells/decidim/collapsible_authors_cell.rb +32 -0
  11. data/app/cells/decidim/invitations_toggle/content.erb +1 -0
  12. data/app/cells/decidim/invitations_toggle/label.erb +1 -0
  13. data/app/cells/decidim/invitations_toggle_cell.rb +27 -0
  14. data/app/cells/decidim/toggle/show.erb +8 -0
  15. data/app/cells/decidim/toggle_cell.rb +42 -0
  16. data/app/cells/decidim/tos_page/refuse_btn_modal.erb +25 -14
  17. data/app/commands/decidim/create_omniauth_registration.rb +1 -1
  18. data/app/commands/decidim/create_registration.rb +1 -1
  19. data/app/commands/decidim/create_report.rb +10 -10
  20. data/app/commands/decidim/invite_friends.rb +48 -0
  21. data/app/commands/decidim/invite_user.rb +4 -2
  22. data/app/commands/decidim/unsubscribe_settings.rb +3 -3
  23. data/app/commands/decidim/update_notifications_settings.rb +1 -1
  24. data/app/controllers/concerns/decidim/needs_tos_accepted.rb +6 -1
  25. data/app/controllers/decidim/data_portability_controller.rb +55 -0
  26. data/app/controllers/decidim/devise/invitations_controller.rb +1 -0
  27. data/app/controllers/decidim/invitations_controller.rb +32 -0
  28. data/app/controllers/decidim/newsletters_opt_in_controller.rb +31 -0
  29. data/app/forms/decidim/account_form.rb +1 -1
  30. data/app/forms/decidim/invitations_form.rb +37 -0
  31. data/app/forms/decidim/notifications_settings_form.rb +5 -0
  32. data/app/forms/decidim/omniauth_registration_form.rb +1 -1
  33. data/app/forms/decidim/registration_form.rb +7 -1
  34. data/app/helpers/decidim/cells_helper.rb +44 -0
  35. data/app/jobs/decidim/data_portability_export_job.rb +21 -0
  36. data/app/jobs/decidim/newsletters_opt_in_job.rb +11 -0
  37. data/app/mailers/decidim/export_mailer.rb +13 -0
  38. data/app/mailers/decidim/newsletters_opt_in_mailer.rb +15 -0
  39. data/app/models/decidim/coauthorship.rb +23 -0
  40. data/app/models/decidim/follow.rb +10 -0
  41. data/app/models/decidim/identity.rb +10 -0
  42. data/app/models/decidim/messaging/conversation.rb +10 -0
  43. data/app/models/decidim/notification.rb +10 -0
  44. data/app/models/decidim/participatory_space_private_user.rb +10 -0
  45. data/app/models/decidim/report.rb +10 -0
  46. data/app/models/decidim/user.rb +16 -1
  47. data/app/models/decidim/user_group.rb +9 -0
  48. data/app/services/decidim/action_authorizer.rb +1 -1
  49. data/app/uploaders/decidim/avatar_uploader.rb +6 -2
  50. data/app/uploaders/decidim/data_portability_uploader.rb +19 -0
  51. data/app/views/decidim/data_portability/export.html.erb +1 -0
  52. data/app/views/decidim/data_portability/show.html.erb +5 -0
  53. data/app/views/decidim/devise/invitations/edit.html.erb +1 -1
  54. data/app/views/decidim/devise/shared/_newsletter_modal.html.erb +13 -13
  55. data/app/views/decidim/export_mailer/data_portability_export.html.erb +2 -0
  56. data/app/views/decidim/invitations/index.html.erb +48 -0
  57. data/app/views/decidim/newsletters_opt_in_mailer/notify.html.erb +23 -0
  58. data/app/views/decidim/profiles/_user.html.erb +1 -1
  59. data/app/views/devise/mailer/invite_friend.html.erb +27 -0
  60. data/app/views/devise/mailer/invite_friend.text.erb +19 -0
  61. data/app/views/layouts/decidim/_user_menu.html.erb +1 -0
  62. data/config/locales/ca.yml +68 -2
  63. data/config/locales/en.yml +73 -3
  64. data/config/locales/es-PY.yml +67 -1
  65. data/config/locales/es.yml +67 -1
  66. data/config/locales/eu.yml +68 -2
  67. data/config/locales/fi.yml +69 -3
  68. data/config/locales/fr.yml +136 -70
  69. data/config/locales/gl.yml +69 -3
  70. data/config/locales/it.yml +69 -3
  71. data/config/locales/nl.yml +69 -3
  72. data/config/locales/pl.yml +69 -3
  73. data/config/locales/pt-BR.yml +69 -3
  74. data/config/locales/pt.yml +69 -3
  75. data/config/locales/ru.yml +45 -2
  76. data/config/locales/sv.yml +69 -3
  77. data/config/locales/uk.yml +61 -2
  78. data/config/routes.rb +10 -0
  79. data/db/migrate/20171212103803_create_unique_nicknames.rb +1 -1
  80. data/db/migrate/20180221101934_fix_nickname_index.rb +3 -1
  81. data/db/migrate/20180427141253_create_coauthorships.rb +13 -0
  82. data/db/migrate/20180611121852_change_newsletter_notification_type_value.rb +21 -0
  83. data/lib/decidim/api/authorable_interface.rb +10 -1
  84. data/lib/decidim/authorable.rb +4 -1
  85. data/lib/decidim/coauthorable.rb +69 -0
  86. data/lib/decidim/component_manifest.rb +4 -0
  87. data/lib/decidim/core.rb +10 -0
  88. data/lib/decidim/core/engine.rb +5 -0
  89. data/lib/decidim/core/test.rb +1 -0
  90. data/lib/decidim/core/test/factories.rb +9 -1
  91. data/lib/decidim/core/test/shared_examples/coauthorable.rb +111 -0
  92. data/lib/decidim/core/test/shared_examples/coauthorable_interface_examples.rb +31 -0
  93. data/lib/decidim/core/test/shared_examples/simple_event.rb +7 -1
  94. data/lib/decidim/core/version.rb +1 -1
  95. data/lib/decidim/data_portability.rb +29 -0
  96. data/lib/decidim/data_portability_file_reader.rb +56 -0
  97. data/lib/decidim/data_portability_file_zipper.rb +55 -0
  98. data/lib/decidim/data_portability_serializers.rb +23 -0
  99. data/lib/decidim/data_portability_serializers/data_portability_conversation_serializer.rb +42 -0
  100. data/lib/decidim/data_portability_serializers/data_portability_follow_serializer.rb +23 -0
  101. data/lib/decidim/data_portability_serializers/data_portability_identity_serializer.rb +25 -0
  102. data/lib/decidim/data_portability_serializers/data_portability_notification_serializer.rb +26 -0
  103. data/lib/decidim/data_portability_serializers/data_portability_participatory_space_private_user_serializer.rb +25 -0
  104. data/lib/decidim/data_portability_serializers/data_portability_report_serializer.rb +36 -0
  105. data/lib/decidim/data_portability_serializers/data_portability_user_group_serializer.rb +21 -0
  106. data/lib/decidim/data_portability_serializers/data_portability_user_serializer.rb +55 -0
  107. data/lib/decidim/events.rb +1 -0
  108. data/lib/decidim/events/coauthor_event.rb +42 -0
  109. data/lib/decidim/exporters/csv.rb +0 -1
  110. data/lib/decidim/form_builder.rb +1 -2
  111. data/lib/decidim/nicknamizable.rb +15 -4
  112. data/lib/decidim/participable.rb +7 -0
  113. data/lib/decidim/participatory_space_manifest.rb +4 -0
  114. data/lib/devise/models/decidim_newsletterable.rb +60 -0
  115. data/lib/tasks/decidim_tasks.rake +29 -0
  116. metadata +73 -28
@@ -3,6 +3,8 @@
3
3
  module Decidim
4
4
  # Store user's social identities
5
5
  class Identity < ApplicationRecord
6
+ include Decidim::DataPortability
7
+
6
8
  belongs_to :user, foreign_key: :decidim_user_id, class_name: "Decidim::User"
7
9
  belongs_to :organization, foreign_key: :decidim_organization_id, class_name: "Decidim::Organization"
8
10
 
@@ -11,6 +13,14 @@ module Decidim
11
13
 
12
14
  validate :same_organization
13
15
 
16
+ def self.user_collection(user)
17
+ where(decidim_user_id: user.id)
18
+ end
19
+
20
+ def self.export_serializer
21
+ Decidim::DataPortabilitySerializers::DataPortabilityIdentitySerializer
22
+ end
23
+
14
24
  private
15
25
 
16
26
  def same_organization
@@ -8,6 +8,8 @@ module Decidim
8
8
  # a group or a one-to-one conversation.
9
9
  #
10
10
  class Conversation < ApplicationRecord
11
+ include Decidim::DataPortability
12
+
11
13
  has_many :participations, foreign_key: :decidim_conversation_id,
12
14
  class_name: "Decidim::Messaging::Participation",
13
15
  dependent: :destroy,
@@ -126,6 +128,14 @@ module Decidim
126
128
  def unread_count(user)
127
129
  receipts.unread_by(user).count
128
130
  end
131
+
132
+ def self.user_collection(user)
133
+ Decidim::Messaging::UserConversations.for(user)
134
+ end
135
+
136
+ def self.export_serializer
137
+ Decidim::DataPortabilitySerializers::DataPortabilityConversationSerializer
138
+ end
129
139
  end
130
140
  end
131
141
  end
@@ -2,11 +2,21 @@
2
2
 
3
3
  module Decidim
4
4
  class Notification < ApplicationRecord
5
+ include Decidim::DataPortability
6
+
5
7
  belongs_to :resource, foreign_key: "decidim_resource_id", foreign_type: "decidim_resource_type", polymorphic: true
6
8
  belongs_to :user, foreign_key: "decidim_user_id", class_name: "Decidim::User"
7
9
 
8
10
  def event_class_instance
9
11
  @event_class_instance ||= event_class.constantize.new(resource: resource, event_name: event_name, user: user, extra: extra)
10
12
  end
13
+
14
+ def self.user_collection(user)
15
+ where(decidim_user_id: user.id)
16
+ end
17
+
18
+ def self.export_serializer
19
+ Decidim::DataPortabilitySerializers::DataPortabilityNotificationSerializer
20
+ end
11
21
  end
12
22
  end
@@ -3,11 +3,21 @@
3
3
  module Decidim
4
4
  # This class gives a given User access to a given private ParticipatorySpacePrivateUser
5
5
  class ParticipatorySpacePrivateUser < ApplicationRecord
6
+ include Decidim::DataPortability
7
+
6
8
  belongs_to :user, class_name: "Decidim::User", foreign_key: :decidim_user_id
7
9
  belongs_to :privatable_to, polymorphic: true
8
10
 
9
11
  validate :user_and_participatory_space_same_organization
10
12
 
13
+ def self.user_collection(user)
14
+ where(decidim_user_id: user.id)
15
+ end
16
+
17
+ def self.export_serializer
18
+ Decidim::DataPortabilitySerializers::DataPortabilityParticipatorySpacePrivateUserSerializer
19
+ end
20
+
11
21
  private
12
22
 
13
23
  # Private: check if the participatory space and the user have the same organization
@@ -3,6 +3,8 @@
3
3
  module Decidim
4
4
  # A reportable can be reported one time for each user.
5
5
  class Report < ApplicationRecord
6
+ include Decidim::DataPortability
7
+
6
8
  REASONS = %w(spam offensive does_not_belong).freeze
7
9
 
8
10
  belongs_to :moderation, foreign_key: "decidim_moderation_id", class_name: "Decidim::Moderation"
@@ -13,6 +15,14 @@ module Decidim
13
15
  validates :reason, inclusion: { in: REASONS }
14
16
  validate :user_and_moderation_same_organization
15
17
 
18
+ def self.user_collection(user)
19
+ where(decidim_user_id: user.id)
20
+ end
21
+
22
+ def self.export_serializer
23
+ Decidim::DataPortabilitySerializers::DataPortabilityReportSerializer
24
+ end
25
+
16
26
  private
17
27
 
18
28
  # Private: check if the moderation and the user have the same organization
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_dependency "devise/models/decidim_validatable"
4
+ require_dependency "devise/models/decidim_newsletterable"
4
5
  require "valid_email2"
5
6
 
6
7
  module Decidim
@@ -10,12 +11,14 @@ module Decidim
10
11
  include Resourceable
11
12
  include Decidim::Followable
12
13
  include Decidim::Loggable
14
+ include Decidim::DataPortability
13
15
 
14
16
  OMNIAUTH_PROVIDERS = [:facebook, :twitter, :google_oauth2, (:developer if Rails.env.development?)].compact
15
17
  ROLES = %w(admin user_manager).freeze
16
18
 
17
19
  devise :invitable, :database_authenticatable, :registerable, :confirmable, :timeoutable,
18
20
  :recoverable, :rememberable, :trackable, :decidim_validatable,
21
+ :decidim_newsletterable,
19
22
  :omniauthable, omniauth_providers: OMNIAUTH_PROVIDERS,
20
23
  request_keys: [:env], reset_password_keys: [:decidim_organization_id, :email],
21
24
  confirmation_keys: [:decidim_organization_id, :email]
@@ -30,7 +33,7 @@ module Decidim
30
33
  has_many :following_follows, foreign_key: "decidim_user_id", class_name: "Decidim::Follow", dependent: :destroy
31
34
 
32
35
  validates :name, presence: true, unless: -> { deleted? }
33
- validates :nickname, presence: true, unless: -> { deleted? || managed? }, length: { maximum: Decidim::User.nickname_max_length }
36
+ validates :nickname, presence: true, unless: -> { deleted? || managed? || name.blank? }, length: { maximum: Decidim::User.nickname_max_length }
34
37
  validates :locale, inclusion: { in: :available_locales }, allow_blank: true
35
38
  validates :tos_agreement, acceptance: true, allow_nil: false, on: :create
36
39
  validates :tos_agreement, acceptance: true, if: :user_invited?
@@ -137,6 +140,18 @@ module Decidim
137
140
  )
138
141
  end
139
142
 
143
+ def self.user_collection(user)
144
+ where(id: user.id)
145
+ end
146
+
147
+ def self.export_serializer
148
+ Decidim::DataPortabilitySerializers::DataPortabilityUserSerializer
149
+ end
150
+
151
+ def self.data_portability_images(user)
152
+ user_collection(user).map(&:avatar)
153
+ end
154
+
140
155
  def tos_accepted?
141
156
  return true if managed
142
157
  return false if accepted_tos_version.nil?
@@ -5,6 +5,7 @@ module Decidim
5
5
  class UserGroup < ApplicationRecord
6
6
  include Decidim::Traceable
7
7
  include Decidim::Loggable
8
+ include Decidim::DataPortability
8
9
 
9
10
  belongs_to :organization, foreign_key: "decidim_organization_id", class_name: "Decidim::Organization"
10
11
 
@@ -42,6 +43,14 @@ module Decidim
42
43
  verified_at.blank? && rejected_at.blank?
43
44
  end
44
45
 
46
+ def self.user_collection(user)
47
+ user.user_groups
48
+ end
49
+
50
+ def self.export_serializer
51
+ Decidim::DataPortabilitySerializers::DataPortabilityUserGroupSerializer
52
+ end
53
+
45
54
  private
46
55
 
47
56
  # Private: Checks if the state user group is correct.
@@ -28,7 +28,7 @@ module Decidim
28
28
  raise AuthorizationError, "Missing data" unless component && action
29
29
 
30
30
  status_code, data = if authorization_handler_name
31
- authorization_handler.authorize(authorization, permission_options)
31
+ authorization_handler.authorize(authorization, permission_options, component)
32
32
  else
33
33
  [:ok, {}]
34
34
  end
@@ -7,11 +7,15 @@ module Decidim
7
7
 
8
8
  process :validate_dimensions
9
9
 
10
- version :big do
10
+ version :profile do
11
+ process resize_to_fill: [536, 640] # double the size, for retina displays
12
+ end
13
+
14
+ version :big, from_version: :profile do
11
15
  process resize_to_fit: [80, 80]
12
16
  end
13
17
 
14
- version :thumb do
18
+ version :thumb, from_version: :big do
15
19
  process resize_to_fit: [40, 40]
16
20
  end
17
21
 
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ # This class deals with saving data portability Zip Files to App
5
+ class DataPortabilityUploader < CarrierWave::Uploader::Base
6
+ # Override the directory where uploaded files will be stored.
7
+ # def store_dir
8
+ # default_path = "tmp/data-portability/"
9
+ # File.join(Rails.root, default_path)
10
+ # end
11
+
12
+ def store_dir
13
+ default_path = "tmp/data-portability/"
14
+
15
+ return File.join(Decidim.base_uploads_path, default_path) if Decidim.base_uploads_path.present?
16
+ default_path
17
+ end
18
+ end
19
+ end
@@ -0,0 +1 @@
1
+ <%= t(".ready") %>
@@ -0,0 +1,5 @@
1
+ <div class="row data-portability">
2
+ <strong><%= t(".download_data") %></strong>
3
+ <p><%= t(".download_data_description", user_email: current_user.email).html_safe %></p>
4
+ <%= button_to t(".request_data"), export_data_portability_path, class: "button secondary", data: { disable: true } %>
5
+ </div>
@@ -56,7 +56,7 @@
56
56
  <legend><%= t("newsletter_title", scope: "decidim.devise.registrations.new") %></legend>
57
57
  <fieldset>
58
58
  <div class="field">
59
- <%= f.check_box :newsletter_notifications, label: t("newsletter", scope: "decidim.devise.registrations.new") %>
59
+ <%= check_box_tag :"#{resource_name}[newsletter_notifications]", label: t("newsletter", scope: "decidim.devise.registrations.new") %>
60
60
  </div>
61
61
  </fieldset>
62
62
  </div>
@@ -1,25 +1,25 @@
1
1
  <div class="reveal" id="sign-up-newsletter-modal" data-reveal>
2
2
  <div class="reveal__header">
3
3
  <h3 class="reveal__title"><%= t(".title") %></h3>
4
- <button class="close-button" data-close aria-label="Close modal"
4
+ <button class="close-button" data-close aria-label="<%= t(".buttons.close_modal") %>"
5
5
  type="button">
6
6
  <span aria-hidden="true">&times;</span>
7
7
  </button>
8
8
  </div>
9
9
 
10
10
  <div class="row">
11
- <div class="columns medium-10 medium-centered">
12
- <p><%= t(".notice") %></p>
13
- </div>
14
- <div class="columns medium-10 medium-centered">
15
- <div class="row">
16
- <div class="columns medium-6">
17
- <button type="buton" class="check-newsletter clear button secondary expanded" data-check=false><%= t(".buttons.uncheck") %></button>
18
- </div>
19
- <div class="columns medium-6">
20
- <button type="buton" class="check-newsletter button expanded" data-check=true><%= t(".buttons.check") %></button>
21
- </div>
22
- </div>
11
+ <%= t(".notice").html_safe %>
12
+ </div>
13
+
14
+ <div class="row">
15
+ <div class="column flex-center">
16
+ <button type="buton" class="check-newsletter clear button secondary expanded" data-check=false>
17
+ <%= t(".buttons.uncheck") %>
18
+ </button>
19
+
20
+ <button type="buton" class="check-newsletter button expanded" data-check=true>
21
+ <%= t(".buttons.check") %>
22
+ </button>
23
23
  </div>
24
24
  </div>
25
25
  </div>
@@ -0,0 +1,2 @@
1
+ <%= t(".click_button", date: l(Decidim.data_portability_expiry_time.from_now, format: :decidim_short) ).html_safe %><br />
2
+ <%= link_to t(".download"), download_file_data_portability_url(host: @organization.host, token: @token), class: "button expanded hollow button--sc" %>
@@ -0,0 +1,48 @@
1
+ <main class="wrapper">
2
+ <div class="row collapse">
3
+ <div class="columns medium-9 medium-centered">
4
+ <div class="card">
5
+ <div class="card__content">
6
+ <h3><%== t(".invitations_title", organization_name: content_tag(:strong, current_organization.name)) %></h3>
7
+ <p><%= t(".invitations_subtitle") %></p>
8
+ <%= decidim_form_for @form, url: account_invitations_path do |form| %>
9
+ <div class="row collapse mt-sm mb-s">
10
+ <% 3.times do |index| %>
11
+ <div class="row">
12
+ <div class="columns medium-6">
13
+ <label>
14
+ <%= t(".friend_email", index: 2 * index + 1) %>
15
+ <%= form.text_field "email_#{2 * index + 1}", placeholder: "email@example.org", required: false, label: false %>
16
+ </label>
17
+ </div>
18
+ <div class="columns medium-6">
19
+ <label>
20
+ <%= t(".friend_email", index: 2 * index + 2) %>
21
+ <%= form.text_field "email_#{2 * index + 2}", placeholder: "email@example.org", required: false, label: false %>
22
+ </label>
23
+ </div>
24
+ </div>
25
+ <% end %>
26
+ </div>
27
+ <div class="row collapse mb-sm">
28
+ <div class="text-medium">
29
+ <%= cell(
30
+ "decidim/toggle",
31
+ nil,
32
+ label: cell("decidim/invitations_toggle").label,
33
+ content: cell("decidim/invitations_toggle", nil, form: form).content
34
+ ) %>
35
+ </div>
36
+ </div>
37
+ <%= form.submit t(".invite"), class: "button expanded" %>
38
+ <% end %>
39
+ </div>
40
+ </div>
41
+ </div>
42
+ </div>
43
+ <div class="row collapse">
44
+ <div class="columns text-center">
45
+ <%= link_to t(".visit_your_profile"), decidim.profile_path(current_user.nickname), class: "button secondary light" %>
46
+ </div>
47
+ </div>
48
+ </main>
@@ -0,0 +1,23 @@
1
+ <p><%= t ".hello" %></p>
2
+
3
+ <p><%= t ".body_1", organization_name: h(@organization.name) %></p>
4
+
5
+ <p><%= t ".body_2" %></p>
6
+
7
+ <table class="button radius" style="margin: 16px auto;">
8
+ <tr>
9
+ <td>
10
+ <table>
11
+ <tr>
12
+ <td>
13
+ <%= link_to t(".button"), decidim.newsletters_opt_in_url(token: @token, host: @organization.host), method: "PUT", class: "button", target: "_blank" %>
14
+ </td>
15
+ </tr>
16
+ </table>
17
+ </td>
18
+ </tr>
19
+ </table>
20
+
21
+ <p><%= t ".body_3" %></p>
22
+
23
+ <p><%= t(".greetings", organization_name: h(@organization.name), organization_url: decidim.root_url(host: @organization.host)).html_safe %></p>
@@ -1,6 +1,6 @@
1
1
  <% present(user) do |profile_user| %>
2
2
  <div class="card">
3
- <%= image_tag profile_user.avatar_url(:big), class: "card__image card__image--larger" %>
3
+ <%= image_tag profile_user.avatar_url(:profile), class: "card__image card__image--larger" %>
4
4
  <div class="card__content">
5
5
  <h5>
6
6
  <div><strong><%= profile_user.name %></strong></div>
@@ -0,0 +1,27 @@
1
+ <p><%= t("devise.mailer.invitation_instructions.hello", email: @resource.name) %></p>
2
+
3
+ <p>
4
+ <%= t("devise.mailer.invitation_instructions.invited_you_as_friend", invited_by: @resource.invited_by.name, application: @resource.organization.name) %>
5
+ </p>
6
+
7
+ <% if @opts[:custom_text].present? %>
8
+ <p><%= t("devise.mailer.invite_friend.friend_custom_text") %></p>
9
+
10
+ <p>
11
+ <em>
12
+ <%= @opts[:custom_text] %>
13
+ </em>
14
+ </p>
15
+ <% end %>
16
+
17
+ <p>
18
+ <%= t("devise.mailer.invite_friend.accept_invitation") %>
19
+ </p>
20
+
21
+ <p><%= link_to t("devise.mailer.invitation_instructions.accept"), accept_invitation_url(@resource, invitation_token: @token, invite_redirect: decidim_admin.root_path, host: @resource.organization.host) %></p>
22
+
23
+ <% if @resource.invitation_due_at %>
24
+ <p><%= t("devise.mailer.invitation_instructions.accept_until", due_date: l(@resource.invitation_due_at, format: :long)) %></p>
25
+ <% end %>
26
+
27
+ <p><%= t("devise.mailer.invitation_instructions.ignore").html_safe %></p>
@@ -0,0 +1,19 @@
1
+ <%= t("devise.mailer.invitation_instructions.hello", email: @resource.name) %>
2
+
3
+ <%= t("devise.mailer.invitation_instructions.invited_you_as_friend", invited_by: @resource.invited_by.name, application: @resource.organization.name) %>
4
+
5
+ <% if @opts[:custom_text].present? %>
6
+ <%= t("devise.mailer.invite_friend.friend_custom_text") %>
7
+
8
+ <%= @opts[:custom_text] %>
9
+ <% end %>
10
+
11
+ <%= t("devise.mailer.invite_friend.accept_invitation") %>
12
+
13
+ <%= accept_invitation_url(@resource, invitation_token: @token, invite_redirect: decidim_admin.root_path, host: @resource.organization.host) %>
14
+
15
+ <% if @resource.invitation_due_at %>
16
+ <%= t("devise.mailer.invitation_instructions.accept_until", due_date: l(@resource.invitation_due_at, format: :long)) %>
17
+ <% end %>
18
+
19
+ <%= t("devise.mailer.invitation_instructions.ignore").html_safe %>
@@ -4,6 +4,7 @@
4
4
  <% end %>
5
5
  <li><%= link_to t(".notifications"), decidim.profile_notifications_path(current_user.nickname) %></li>
6
6
  <li><%= link_to t(".conversations"), decidim.conversations_path %></li>
7
+ <li><%= link_to t(".invite_friends"), decidim.account_invitations_path %></li>
7
8
  <% if allowed_to? :read, :admin_dashboard %>
8
9
  <li><%= link_to t(".admin_dashboard"), decidim_admin.root_path %></li>
9
10
  <% end %>