Module: CommunicationsHelper
- Defined in:
- app/helpers/communications_helper.rb
Overview
View helper: communications.
Instance Method Summary collapse
- #attachment_name(upload) ⇒ Object
-
#clean_received_body(body) ⇒ Object
Strips quoted/forwarded content from a plain-text received email body for display.
- #combo_category_select_options(category = nil) ⇒ Object
- #communication_actions(c) ⇒ Object
- #communication_recipient_delete_button(f) ⇒ Object
- #communication_recipient_state_label(communication_recipient) ⇒ Object
- #communication_state_details(cr) ⇒ Object
- #communication_state_label(communication) ⇒ Object
-
#email_links_in_new_tab(html) ⇒ String
Rewrites external (http/https) links in a displayed email body so they open in a new browser tab instead of "in place".
- #email_template_option(template) ⇒ Object
- #email_templates_for_user(include_email_template_id) ⇒ Object
- #preview_communication_body(communication) ⇒ Object
- #setup_communication(communication) ⇒ Object
- #translate_cp_category_to_combo(category) ⇒ Object
Instance Method Details
#attachment_name(upload) ⇒ Object
10 11 12 |
# File 'app/helpers/communications_helper.rb', line 10 def (upload) upload. end |
#clean_received_body(body) ⇒ Object
Strips quoted/forwarded content from a plain-text received email body for display.
Handles two common patterns:
- "On , wrote:" reply blocks (via EmailReplyParser)
- "From: / To: / Date: / Subject:" forwarded message header blocks (via regex)
164 165 166 167 168 |
# File 'app/helpers/communications_helper.rb', line 164 def clean_received_body(body) text = EmailReplyParser.parse_reply(body.to_s) # Strip forwarded-message header blocks: "From:\nTo: ..." and everything after text.sub(/\n+\s*From:[^\n]*\n[\t ]*(?:To|Sent|Date|Cc|Subject):.*\z/m, '').strip end |
#combo_category_select_options(category = nil) ⇒ Object
82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'app/helpers/communications_helper.rb', line 82 def (category = nil) opts = [] if category.nil? || (category == 'email') opts += [ ['Email TO', 'email_to'], ['Email CC', 'email_cc'], ['Email BCC', 'email_bcc'] ] end opts += [%w[Fax fax]] if category.nil? || (category == 'fax') opts end |
#communication_actions(c) ⇒ Object
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'app/helpers/communications_helper.rb', line 56 def communication_actions(c) [].tap do |cmds| cmds << c.human_state_name.titleize cmds << link_to(fa_icon('pen-to-square', text: 'Edit'), edit_communication_path(@communication)) if (c.draft? || c.exception?) && can?(:update, c) if can?(:destroy, c) && !c.sent? cmds << link_to(fa_icon('trash', text: 'Delete'), communication_path(@communication), data: { turbo_confirm: 'Delete for sure?', turbo_method: :delete }) end cmds << link_to(fa_icon('repeat', text: 'Resend this email'), resend_email_communication_path(@communication)) if can?(:create, Communication) && !@communication.draft? && @communication.direction_outbound? cmds << link_to(fa_icon('copy', text: 'Copy into new blank communication'), copy_communication_path(@communication)) if can?(:create, Communication) && !@communication.draft? if @communication.can_queue? cmds << link_to(fa_icon('envelope', text: 'Queue for delivery'), communication_path(@communication, communication: { state_event: :queue }), data: { turbo_method: :put }) end cmds << link_to(fa_icon('arrow-rotate-left', text: 'Back to Draft'), communication_path(@communication, communication: { state_event: :unqueue }), data: { turbo_method: :put }) if @communication.can_unqueue? cmds << link_to(fa_icon('envelope', text: 'Send Now'), send_now_communication_path(@communication), data: { turbo_method: :put }) if @communication.draft? || @communication.queued? if @communication.can_resend? cmds << link_to(fa_icon('envelope', text: 'Queue to Resend'), communication_path(@communication, communication: { state_event: :resend }), data: { turbo_method: :put }) end cmds << link_to(fa_icon('reply', text: 'Reply'), reply_communication_path(@communication)) cmds << link_to(fa_icon('reply-all', text: 'Reply All'), reply_all_communication_path(@communication)) if @communication.communication_recipients.many? cmds << link_to(fa_icon('bell', text: 'Events'), events_communication_path(@communication)) end end |
#communication_recipient_delete_button(f) ⇒ Object
37 38 39 40 41 42 43 44 45 46 47 |
# File 'app/helpers/communications_helper.rb', line 37 def (f) if f.object.persisted? content_tag(:div, class: 'btn btn-outline-warning') do concat f.hidden_field '_destroy' concat f.label '_destroy', fa_icon('trash'), class: 'm-0 p-0' concat f.check_box '_destroy', class: 'destroy' end else link_to(fa_icon('trash'), '#', class: 'btn btn-outline-warning trash-remove', data: { 'class-to-remove': '.communication_recipient' }) end end |
#communication_recipient_state_label(communication_recipient) ⇒ Object
109 110 111 112 113 114 |
# File 'app/helpers/communications_helper.rb', line 109 def communication_recipient_state_label(communication_recipient) label_class = { processed: 'secondary', dropped: 'danger', delivered: 'success', deferred: 'warning', bounced: 'danger', opened: 'success', ok: 'success', clicked: 'success', spammed: 'danger', unsubscribed: 'warning' }[communication_recipient.state.to_sym] || 'default' content_tag :span, communication_recipient.human_state_name.upcase, class: "badge bg-#{label_class}" end |
#communication_state_details(cr) ⇒ Object
49 50 51 52 53 54 |
# File 'app/helpers/communications_helper.rb', line 49 def communication_state_details(cr) msg = [] msg << "State triggered at #{cr.state_updated_at.to_fs(:crm_default)}" if cr.state_updated_at msg << "Response: #{cr.state_response}" if cr.state_response.present? raw(msg.join('. ')) end |
#communication_state_label(communication) ⇒ Object
102 103 104 105 106 107 |
# File 'app/helpers/communications_helper.rb', line 102 def communication_state_label(communication) label_class = { exception: 'danger', suppressed: 'danger', queued: 'warning', sent: 'success', received: 'info', draft: 'secondary' }[communication.state.to_sym] || 'default' comm_label = communication.human_state_name.upcase comm_label << ' (Scheduled)' if communication.transmit_at && communication.queued? content_tag :span, comm_label, class: "badge bg-#{label_class}" end |
#email_links_in_new_tab(html) ⇒ String
Rewrites external (http/https) links in a displayed email body so they open
in a new browser tab instead of "in place". Display-only — never apply this to
the stored body, since Communication#compliant_body is the literal payload
handed to CommunicationMailer and preview affordances must not leak into sent
mail.
Outbound/template bodies render inline inside the Activities <turbo-frame>,
where Turbo otherwise intercepts a bare <a> click and loads the destination
into the frame. An explicit target="_blank" sidesteps that (Turbo leaves
links with an explicit target alone) and rel="noopener noreferrer" is the
standard safety companion. Received HTML emails are handled separately via a
<base target> in their srcdoc iframe (see _preview_body.html.erb).
Returns the body unchanged when it has no external anchors, and parses
fragments as fragments so a plain-text or partial body is never wrapped in a
synthetic <html>/<body>.
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
# File 'app/helpers/communications_helper.rb', line 141 def email_links_in_new_tab(html) source = html.to_s return source unless source.match?(/<a[\s>]/i) full_document = source.match?(/<html[\s>]|<!doctype\s+html/i) doc = full_document ? Nokogiri::HTML(source) : Nokogiri::HTML::DocumentFragment.parse(source) rewrote = false doc.css('a[href]').each do |node| next unless node['href'].to_s.match?(%r{\Ahttps?://}i) node['target'] = '_blank' node['rel'] = (node['rel'].to_s.split + %w[noopener noreferrer]).uniq.join(' ') rewrote = true end rewrote ? doc.to_html : source end |
#email_template_option(template) ⇒ Object
27 28 29 30 31 32 33 34 35 |
# File 'app/helpers/communications_helper.rb', line 27 def email_template_option(template) # All templates are selectable, but mark v3 templates in the label label = if template.redactor_4_ready? "#{template.description} [#{template.category}]" else "#{template.description} [#{template.category}] (v3)" end [label, template.id] end |
#email_templates_for_user(include_email_template_id) ⇒ Object
14 15 16 17 18 19 20 21 22 23 24 25 |
# File 'app/helpers/communications_helper.rb', line 14 def email_templates_for_user(include_email_template_id) = {} # Show all templates - Redactor 3 templates are shown but disabled (only v4 can be selected) base_query = EmailTemplate.non_campaign.active.order(:description) person_filter_sql = "resource_type = 'Employee' and resource_id = :employee_id" person_filter_sql = "(#{person_filter_sql}) OR email_templates.id = :email_template_id" if include_email_template_id tpl_pers = base_query.where(person_filter_sql, employee_id: @context_user.id, email_template_id: include_email_template_id) tpl_global = base_query.where(resource_id: nil) ['Private Templates'] = tpl_pers.map { |t| email_template_option(t) } if tpl_pers.present? ['Global Templates'] = tpl_global.map { |t| email_template_option(t) } if tpl_global.present? end |
#preview_communication_body(communication) ⇒ Object
116 117 118 119 120 |
# File 'app/helpers/communications_helper.rb', line 116 def preview_communication_body(communication) return unless communication render partial: '/communications/preview_body', locals: { communication: communication } end |
#setup_communication(communication) ⇒ Object
4 5 6 7 8 |
# File 'app/helpers/communications_helper.rb', line 4 def setup_communication(communication) communication.tap do |c| c.communication_recipients.build(category: ContactPoint::EMAIL, email_method: 'to') unless c.communication_recipients.find { |cr| cr.category == ContactPoint::EMAIL } end end |
#translate_cp_category_to_combo(category) ⇒ Object
95 96 97 98 99 100 |
# File 'app/helpers/communications_helper.rb', line 95 def translate_cp_category_to_combo(category) { 'email' => 'email_to', 'fax' => 'fax' }[category] end |