Module: Crm::WebhookLogsHelper
- Defined in:
- app/helpers/crm/webhook_logs_helper.rb
Overview
View helpers for the CRM webhook logs screens
(Crm::WebhookLogsController): state badges, resource links, payload
formatting, per-row actions, and dashboard stats.
Instance Method Summary collapse
-
#extract_payload_identifier(log) ⇒ ActiveSupport::SafeBuffer?
Extracts a quick identifier from the payload (email, tracking number, transcript id, etc.) rendered as muted small text.
-
#webhook_log_actions(log, include_show_action: true, return_path: nil) ⇒ Array<ActiveSupport::SafeBuffer>
Builds the dropdown action links for a webhook log row, gated on the log's state and the user's abilities.
-
#webhook_log_format_data(log) ⇒ ActiveSupport::SafeBuffer
Pretty-prints the request payload inside a styled block.
-
#webhook_log_format_response(log) ⇒ ActiveSupport::SafeBuffer
Pretty-prints the response payload inside a styled block.
-
#webhook_log_provider_name(log) ⇒ String
Human-friendly provider name for a webhook log.
-
#webhook_log_resource_link(log) ⇒ String, ActiveSupport::SafeBuffer
Builds the resource cell for a webhook log row: a payload identifier plus a link to the mapped resource (or a deleted marker), joined with a line break.
-
#webhook_log_state_badge(log) ⇒ ActiveSupport::SafeBuffer
Renders a Bootstrap badge describing a webhook log's state.
-
#webhook_log_stats ⇒ Hash{Symbol => Integer}
Aggregated counts for the webhook logs dashboard header.
Instance Method Details
#extract_payload_identifier(log) ⇒ ActiveSupport::SafeBuffer?
Extracts a quick identifier from the payload (email, tracking number,
transcript id, etc.) rendered as muted small text.
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'app/helpers/crm/webhook_logs_helper.rb', line 91 def extract_payload_identifier(log) data = log.data || {} identifier = case log.provider when 'sendgrid' data['email'] when 'shipengine' tracking = data.dig('data', 'tracking_number') tracking.present? ? "Track: #{tracking}" : nil when 'oxylabs' data['url']&.truncate(40) when 'assemblyai' transcript_id = data['transcript_id'] transcript_id.present? ? "Transcript: #{transcript_id.truncate(20)}" : nil end # Fallback: try common fields identifier ||= data['email'] || data['tracking_number'] || data['id']&.to_s&.truncate(30) return nil if identifier.blank? tag.small(class: 'text-body-secondary') { identifier } end |
#webhook_log_actions(log, include_show_action: true, return_path: nil) ⇒ Array<ActiveSupport::SafeBuffer>
Builds the dropdown action links for a webhook log row, gated on the
log's state and the user's abilities.
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'app/helpers/crm/webhook_logs_helper.rb', line 122 def webhook_log_actions(log, include_show_action: true, return_path: nil) links = [] (controller: 'crm/webhook_logs', return_path: return_path) do |defaults| # State-dependent actions links << link_to('Process', defaults.url_for(action: :do_process, id: log.id), data: { turbo_method: :post }, class: 'dropdown-item') if log.ready? || log.retry? links << link_to('Reprocess', defaults.url_for(action: :do_reprocess, id: log.id), data: { turbo_method: :post }, class: 'dropdown-item') if log.processed? || log.exception? || log.retry? links << link_to('Archive', defaults.url_for(action: :do_archive, id: log.id), data: { turbo_method: :post }, class: 'dropdown-item') if log.exception? || log.processed? # Standard actions links << link_to('Show', defaults.url_for(action: :show, id: log.id), class: 'dropdown-item') if include_show_action links << link_to('Edit', defaults.url_for(action: :edit, id: log.id), class: 'dropdown-item') if can?(:update, log) if can?(:destroy, log) links << link_to('Delete', defaults.url_for(action: :destroy, id: log.id), data: { turbo_method: :delete, turbo_confirm: 'Delete this webhook log?' }, class: 'dropdown-item text-danger') end end links end |
#webhook_log_format_data(log) ⇒ ActiveSupport::SafeBuffer
Pretty-prints the request payload inside a styled block.
148 149 150 151 152 |
# File 'app/helpers/crm/webhook_logs_helper.rb', line 148 def webhook_log_format_data(log) return tag.pre('No data', class: 'text-body-secondary') if log.data.blank? tag.pre(pretty_json_tag(log.data), class: 'bg-light p-3 rounded') end |
#webhook_log_format_response(log) ⇒ ActiveSupport::SafeBuffer
Pretty-prints the response payload inside a styled block.
158 159 160 161 162 |
# File 'app/helpers/crm/webhook_logs_helper.rb', line 158 def webhook_log_format_response(log) return tag.pre('No response', class: 'text-body-secondary') if log.response_data.blank? tag.pre(pretty_json_tag(log.response_data), class: 'bg-light p-3 rounded') end |
#webhook_log_provider_name(log) ⇒ String
Human-friendly provider name for a webhook log.
38 39 40 |
# File 'app/helpers/crm/webhook_logs_helper.rb', line 38 def webhook_log_provider_name(log) log.provider.to_s.titleize end |
#webhook_log_resource_link(log) ⇒ String, ActiveSupport::SafeBuffer
Builds the resource cell for a webhook log row: a payload identifier
plus a link to the mapped resource (or a deleted marker), joined with
a line break.
49 50 51 52 53 54 55 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 81 82 83 |
# File 'app/helpers/crm/webhook_logs_helper.rb', line 49 def webhook_log_resource_link(log) parts = [] # Always try to extract payload identifier first payload_id = extract_payload_identifier(log) parts << payload_id if payload_id.present? # If resource is mapped, add link if log.resource_type.present? && log.resource_id.present? resource = log.resource resource_link = if resource.nil? tag.span(class: 'text-warning') { "#{log.resource_type} ##{log.resource_id} (deleted)" } else case log.resource_type when 'CallRecord' link_to "CallRecord ##{log.resource_id}", call_record_path(resource) when 'Video' link_to resource.title.truncate(30), video_path(resource) when 'CatalogItem' link_to "CatalogItem ##{log.resource_id}", catalog_item_path(resource) when 'CommunicationRecipient' link_to "Communication ##{resource.communication_id}", communication_path(resource.communication) when 'Shipment' link_to "Shipment ##{log.resource_id}", shipment_path(resource) else "#{log.resource_type} ##{log.resource_id}" end end parts << resource_link end return '-' if parts.empty? safe_join(parts, tag.br) end |
#webhook_log_state_badge(log) ⇒ ActiveSupport::SafeBuffer
Renders a Bootstrap badge describing a webhook log's state.
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'app/helpers/crm/webhook_logs_helper.rb', line 13 def webhook_log_state_badge(log) state = log.state.to_s badge_class = case state when 'pending' then 'bg-info' # Awaiting callback when 'ready' then 'bg-primary' # Callback received, ready to process when 'processing' then 'bg-warning' # Currently processing when 'processed' then 'bg-success' # Completed when 'retry' then 'bg-warning' # Scheduled for retry when 'exception' then 'bg-danger' # Failed when 'archived' then 'bg-secondary' # Archived else 'bg-dark' end label = case state when 'pending' then 'Awaiting Callback' else state.titleize end tag.span(label, class: "badge #{badge_class}") end |
#webhook_log_stats ⇒ Hash{Symbol => Integer}
Aggregated counts for the webhook logs dashboard header.
167 168 169 170 171 172 173 174 175 176 |
# File 'app/helpers/crm/webhook_logs_helper.rb', line 167 def webhook_log_stats { total: WebhookLog.count, awaiting_callback: WebhookLog.where(state: 'pending').count, ready_to_process: WebhookLog.where(state: %w[ready retry]).count, processed: WebhookLog.where(state: 'processed').count, failed: WebhookLog.where(state: 'exception').count, today: WebhookLog.where(created_at: Time.current.beginning_of_day..).count } end |