Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backport 'Add customizable meeting reminders' to 0.27 #85

Open
wants to merge 4 commits into
base: 0.27-backports
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ def copy_meeting!
comments_end_time: form.comments_end_time,
registration_type: form.registration_type,
registration_url: form.registration_url,
reminder_enabled: form.reminder_enabled,
send_reminders_before_hours: form.send_reminders_before_hours,
reminder_message_custom_content: form.reminder_message_custom_content,
**fields_from_meeting
)
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ def create_meeting!
comments_enabled: form.comments_enabled,
comments_start_time: form.comments_start_time,
comments_end_time: form.comments_end_time,
reminder_enabled: form.reminder_enabled,
send_reminders_before_hours: form.reminder_enabled ? form.send_reminders_before_hours : nil,
reminder_message_custom_content: form.reminder_enabled ? form.reminder_message_custom_content : {},
iframe_access_level: form.iframe_access_level
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def schedule_upcoming_meeting_notification
checksum = Decidim::Meetings::UpcomingMeetingNotificationJob.generate_checksum(meeting)

Decidim::Meetings::UpcomingMeetingNotificationJob
.set(wait_until: meeting.start_time - Decidim::Meetings.upcoming_meeting_notification)
.set(wait_until: meeting.start_time - meeting.send_reminders_before_hours.hours)
.perform_later(meeting.id, checksum)
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ def update_meeting!
comments_enabled: form.comments_enabled,
comments_start_time: form.comments_start_time,
comments_end_time: form.comments_end_time,
reminder_enabled: form.reminder_enabled,
send_reminders_before_hours: form.reminder_enabled ? form.send_reminders_before_hours : nil,
reminder_message_custom_content: form.reminder_enabled ? form.reminder_message_custom_content : nil,
iframe_access_level: form.iframe_access_level
)
end
Expand Down Expand Up @@ -102,7 +105,7 @@ def schedule_upcoming_meeting_notification
checksum = Decidim::Meetings::UpcomingMeetingNotificationJob.generate_checksum(meeting)

Decidim::Meetings::UpcomingMeetingNotificationJob
.set(wait_until: meeting.start_time - Decidim::Meetings.upcoming_meeting_notification)
.set(wait_until: meeting.start_time - meeting.send_reminders_before_hours.hours)
.perform_later(meeting.id, checksum)
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ def call
def create_meeting!
parsed_title = Decidim::ContentProcessor.parse_with_processor(:hashtag, form.title, current_organization: form.current_organization).rewrite
parsed_description = Decidim::ContentProcessor.parse(form.description, current_organization: form.current_organization).rewrite
parsed_reminder_message = Decidim::ContentProcessor.parse(form.reminder_message_custom_content, current_organization: form.current_organization).rewrite

params = {
scope: form.scope,
Expand All @@ -56,6 +57,9 @@ def create_meeting!
type_of_meeting: form.clean_type_of_meeting,
component: form.current_component,
published_at: Time.current,
reminder_enabled: form.reminder_enabled,
send_reminders_before_hours: form.reminder_enabled ? form.send_reminders_before_hours : nil,
reminder_message_custom_content: form.reminder_enabled ? { I18n.locale => parsed_reminder_message } : {},
iframe_embed_type: form.iframe_embed_type,
iframe_access_level: form.iframe_access_level
}
Expand All @@ -77,7 +81,7 @@ def schedule_upcoming_meeting_notification
checksum = Decidim::Meetings::UpcomingMeetingNotificationJob.generate_checksum(meeting)

Decidim::Meetings::UpcomingMeetingNotificationJob
.set(wait_until: meeting.start_time - Decidim::Meetings.upcoming_meeting_notification)
.set(wait_until: meeting.start_time - form.send_reminders_before_hours.hours)
.perform_later(meeting.id, checksum)
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ def call
def update_meeting!
parsed_title = Decidim::ContentProcessor.parse_with_processor(:hashtag, form.title, current_organization: form.current_organization).rewrite
parsed_description = Decidim::ContentProcessor.parse(form.description, current_organization: form.current_organization).rewrite
parsed_reminder_message = Decidim::ContentProcessor.parse(form.reminder_message_custom_content, current_organization: form.current_organization).rewrite

Decidim.traceability.update!(
meeting,
Expand All @@ -63,6 +64,9 @@ def update_meeting!
registrations_enabled: form.registrations_enabled,
type_of_meeting: form.clean_type_of_meeting,
online_meeting_url: form.online_meeting_url,
reminder_enabled: form.reminder_enabled,
send_reminders_before_hours: form.reminder_enabled ? form.send_reminders_before_hours : nil,
reminder_message_custom_content: form.reminder_enabled ? { I18n.locale => parsed_reminder_message } : {},
iframe_embed_type: form.iframe_embed_type,
iframe_access_level: form.iframe_access_level
},
Expand Down Expand Up @@ -97,7 +101,7 @@ def schedule_upcoming_meeting_notification
checksum = Decidim::Meetings::UpcomingMeetingNotificationJob.generate_checksum(meeting)

Decidim::Meetings::UpcomingMeetingNotificationJob
.set(wait_until: meeting.start_time - Decidim::Meetings.upcoming_meeting_notification)
.set(wait_until: meeting.start_time - meeting.send_reminders_before_hours.hours)
.perform_later(meeting.id, checksum)
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,38 @@ module Decidim
module Meetings
class UpcomingMeetingEvent < Decidim::Events::SimpleEvent
include Decidim::Meetings::MeetingEvent

i18n_attributes :reminders_before_hours

def email_intro
(custom_message.presence || default_email_intro).to_s.html_safe
end

def i18n_options
{
resource_title: resource_title,
resource_path: resource_path,
resource_url: resource_url,
participatory_space_url: participatory_space_url,
participatory_space_title: participatory_space_title,
reminders_before_hours: resource.send_reminders_before_hours,
scope: event_name
}
end

private

def reminder_message
translated_attribute(resource.reminder_message_custom_content)
end

def default_email_intro
I18n.t("decidim.events.meetings.upcoming_meeting.email_intro", **i18n_options)
end

def custom_message
Decidim::Meetings::MeetingPresenter.new(resource).reminder_message_custom_content
end
end
end
end
17 changes: 17 additions & 0 deletions decidim-meetings/app/forms/decidim/meetings/admin/meeting_form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,14 @@ class MeetingForm < ::Decidim::Meetings::BaseMeetingForm
attribute :comments_start_time, Decidim::Attributes::TimeWithZone
attribute :comments_end_time, Decidim::Attributes::TimeWithZone
attribute :iframe_access_level, String
attribute :reminder_enabled, Boolean, default: true
attribute :send_reminders_before_hours, Integer, default: Decidim::Meetings.upcoming_meeting_notification.in_hours

translatable_attribute :title, String
translatable_attribute :description, String
translatable_attribute :location, String
translatable_attribute :location_hints, String
translatable_attribute :reminder_message_custom_content, String

validates :iframe_embed_type, inclusion: { in: Decidim::Meetings::Meeting.iframe_embed_types }
validates :title, translatable_presence: true
Expand All @@ -41,6 +44,7 @@ class MeetingForm < ::Decidim::Meetings::BaseMeetingForm
validates :scope, presence: true, if: ->(form) { form.decidim_scope_id.present? }
validates :decidim_scope_id, scope_belongs_to_component: true, if: ->(form) { form.decidim_scope_id.present? }
validates :clean_type_of_meeting, presence: true
validates :send_reminders_before_hours, numericality: { only_integer: true, greater_than_or_equal_to: 0, if: :reminder_enabled }
validates(
:iframe_access_level,
inclusion: { in: Decidim::Meetings::Meeting.iframe_access_levels },
Expand Down Expand Up @@ -69,6 +73,19 @@ def number_of_services

alias component current_component

def send_reminders_before_hours
return nil unless reminder_enabled

value = super.presence
value.blank? || value.to_i.zero? ? Decidim::Meetings.upcoming_meeting_notification.in_hours.to_i : value.to_i
end

def reminder_message_custom_content
return {} unless reminder_enabled

super
end

# Finds the Scope from the given decidim_scope_id, uses component scope if missing.
#
# Returns a Decidim::Scope
Expand Down
18 changes: 18 additions & 0 deletions decidim-meetings/app/forms/decidim/meetings/meeting_form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ class MeetingForm < ::Decidim::Meetings::BaseMeetingForm
attribute :registration_terms, String
attribute :iframe_embed_type, String, default: "none"
attribute :iframe_access_level, String
attribute :reminder_enabled, Boolean, default: true
attribute :send_reminders_before_hours, Integer, default: Decidim::Meetings.upcoming_meeting_notification.in_hours
attribute :reminder_message_custom_content, String

validates :iframe_embed_type, inclusion: { in: Decidim::Meetings::Meeting.participants_iframe_embed_types }
validates :title, presence: true
Expand All @@ -34,6 +37,7 @@ class MeetingForm < ::Decidim::Meetings::BaseMeetingForm
validates :scope, presence: true, if: ->(form) { form.decidim_scope_id.present? }
validates :decidim_scope_id, scope_belongs_to_component: true, if: ->(form) { form.decidim_scope_id.present? }
validates :clean_type_of_meeting, presence: true
validates :send_reminders_before_hours, numericality: { only_integer: true, greater_than_or_equal_to: 0, if: :reminder_enabled }
validates(
:iframe_access_level,
inclusion: { in: Decidim::Meetings::Meeting.iframe_access_levels },
Expand All @@ -51,11 +55,25 @@ def map_model(model)
self.location = presenter.location(all_locales: false)
self.location_hints = presenter.location_hints(all_locales: false)
self.registration_terms = presenter.registration_terms(all_locales: false)
self.reminder_message_custom_content = presenter.reminder_message_custom_content(all_locales: false)
self.type_of_meeting = model.type_of_meeting
end

alias component current_component

def send_reminders_before_hours
return nil unless reminder_enabled

value = super.presence
value.blank? || value.to_i.zero? ? Decidim::Meetings.upcoming_meeting_notification.in_hours.to_i : value.to_i
end

def reminder_message_custom_content
return {} unless reminder_enabled

super
end

# Finds the Scope from the given decidim_scope_id, uses the compoenent scope if missing.
#
# Returns a Decidim::Scope
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,12 @@ def registration_email_custom_content(links: false, all_locales: false)
end
end

def reminder_message_custom_content(links: false, extras: true, strip_tags: false, all_locales: false)
return unless meeting

content_handle_locale(meeting.reminder_message_custom_content, all_locales, extras, links, strip_tags)
end

# start time and end time in rfc3339 format removing '-' and ':' symbols
# joined with '/'. This format is used to generate the dates query param
# in google calendars event link
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,19 @@
</div>

<%= render partial: "decidim/comments/admin/shared/availability_fields", locals: { form: form } %>

<div class="row column">
<%= form.check_box :reminder_enabled, label: t("reminder_enabled", scope: "decidim.meetings.admin.meetings.form"), "data-toggle": "customize_reminder_times" %>
</div>

<div id="customize_reminder_times" data-toggler=".hide" class="row column <%= @form.reminder_enabled ? nil : "hide" %>">
<div class="my-4">
<%= form.number_field :send_reminders_before_hours, label: t("send_reminder", scope: "decidim.meetings.admin.meetings.form") %>
<p class="help-text"><%= t("reminder_help_text", scope: "decidim.meetings.admin.meetings.form", default_value: Decidim::Meetings.upcoming_meeting_notification.in_hours.to_i) %></p>
</div>

<%= form.translated :editor, :reminder_message_custom_content, label: t("reminder_message", scope: "decidim.meetings.admin.meetings.form"), hashtaggable: true, help_text: t("reminder_message_help_text", scope: "decidim.meetings.admin.meetings.form") %>
</div>
</div>
</div>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,18 @@
<label><%= t(".disclaimer", organization: current_component.organization.name) %></label><br>
</div>

<div class="row column">
<%= form.check_box :reminder_enabled, label: t("reminder_enabled", scope: "decidim.meetings.admin.meetings.form"), "data-toggle": "customize_reminder_times" %>
</div>

<div id="customize_reminder_times" data-toggler=".hide" class="row column <%= @form.reminder_enabled ? nil : "hide" %>">
<div class="my-4">
<%= form.number_field :send_reminders_before_hours, label: t("send_reminder", scope: "decidim.meetings.admin.meetings.form") %>
<p class="help-text"><%= t("reminder_help_text", scope: "decidim.meetings.admin.meetings.form", default_value: Decidim::Meetings.upcoming_meeting_notification.in_hours.to_i) %></p>
</div>
<%= text_editor_for(form, :reminder_message_custom_content, hashtaggable: true, label: t("reminder_message", scope: "decidim.meetings.admin.meetings.form"), help_text: t("reminder_message_help_text", scope: "decidim.meetings.admin.meetings.form") ) %>
</div>

<div class="field">
<%= form.select(
:user_group_id,
Expand Down
13 changes: 9 additions & 4 deletions decidim-meetings/config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -191,10 +191,10 @@ en:
email_subject: The "%{resource_title}" meeting has enabled registrations.
notification_title: The <a href="%{resource_path}">%{resource_title}</a> meeting has enabled registrations.
upcoming_meeting:
email_intro: The "%{resource_title}" meeting will start in less than 48h.
email_outro: You have received this notification because you are following the "%{resource_title}" meeting. You can unfollow it from the previous link.
email_subject: The "%{resource_title}" meeting will start in less than 48h.
notification_title: The <a href="%{resource_path}">%{resource_title}</a> meeting will start in less than 48h.
email_intro: The "%{resource_title}" meeting will start in less than %{reminders_before_hours}h.
email_outro: You have received this notification because you are following the %{resource_title} meeting. You can unfollow it from the previous link.
email_subject: The "%{resource_title}" meeting will start in less than %{reminders_before_hours}h.
notification_title: The <a href="%{resource_path}">%{resource_title}</a> meeting will start in less than %{reminders_before_hours}h.
forms:
meetings:
attendees_count_help_text: Don't forget to include the total number of attendees at your meeting, whether in person, online or hybrid.
Expand Down Expand Up @@ -318,9 +318,14 @@ en:
location_hints_help: 'Location hints: additional info. Example: the floor of the building if it is an in-person meeting, or the meeting password if it is an online meeting with restricted access.'
online_meeting_url_help: 'Link: allow participants to connect directly to your meeting'
registration_url_help: 'Link: allow participants to go on the external service you are using for registrations'
reminder_enabled: Reminder enabled
reminder_help_text: Participants will receive an email the number of hours specified in advance of themeeting. If left empty or zero, the reminder will be sent at the default configured value of %{default_value} hours.
reminder_message: Reminder message
reminder_message_help_text: Customize the message if necessary. This will be ignored if no reminder is scheduled.
select_a_meeting_type: Please select a meeting type
select_a_registration_type: Please select a registration type
select_an_iframe_access_level: Please select an iframe access level
send_reminder: Send a reminder for this meeting
show_embedded_iframe_help: 'Only a few services allow embedding in meeting or live event from the following domains: %{domains}'
index:
title: Meetings
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true

class AddReminderCustomizationToDecidimMeetings < ActiveRecord::Migration[6.0]
def change
add_column :decidim_meetings_meetings, :reminder_enabled, :boolean
add_column :decidim_meetings_meetings, :send_reminders_before_hours, :integer
add_column :decidim_meetings_meetings, :reminder_message_custom_content, :jsonb
end
end
2 changes: 1 addition & 1 deletion decidim-meetings/lib/decidim/meetings.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ module Meetings

# Public Setting that defines the interval when the upcoming meeting will be sent
config_accessor :upcoming_meeting_notification do
2.days
48.hours
end

config_accessor :embeddable_services do
Expand Down
3 changes: 3 additions & 0 deletions decidim-meetings/lib/decidim/meetings/test/factories.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@
registration_type { :on_this_platform }
type_of_meeting { :in_person }
component { build(:meeting_component) }
reminder_enabled { true }
send_reminders_before_hours { 48 }
reminder_message_custom_content { {} }
iframe_access_level { :all }
iframe_embed_type { :none }

Expand Down
4 changes: 4 additions & 0 deletions decidim-meetings/spec/commands/admin/copy_meeting_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ module Decidim::Meetings
comments_enabled: meeting.comments_enabled,
comments_start_time: meeting.comments_start_time,
comments_end_time: meeting.comments_end_time,
reminder_enabled: meeting.reminder_enabled,
send_reminders_before_hours: meeting.send_reminders_before_hours,
reminder_message_custom_content: meeting.reminder_message_custom_content,
registration_type: :on_this_platform,
registration_url: meeting.registration_url,
type_of_meeting: meeting.type_of_meeting
Expand Down Expand Up @@ -77,6 +80,7 @@ module Decidim::Meetings
expect(new_meeting.category).to eq(old_meeting.category)
expect(new_meeting.component).to eq(old_meeting.component)
expect(new_meeting.component).not_to eq(be_published)
expect(new_meeting.reminder_message_custom_content).to eq(old_meeting.reminder_message_custom_content)

new_meeting.services.each_with_index do |service, index|
expect(service.title).to eq(services[index]["title"])
Expand Down
Loading
Loading