Class: Crm::UploadCardComponent
- Inherits:
-
ViewComponent::Base
- Object
- ViewComponent::Base
- Crm::UploadCardComponent
- Defined in:
- app/components/crm/upload_card_component.rb
Overview
ViewComponent: renders the upload card block.
Shows a single Upload as a card with a thumbnail, attachment name,
file size, a Fancybox preview link, a hidden +upload_ids[]+ field for
form submission, and an optional remove button.
Instance Attribute Summary collapse
- #context_class ⇒ Upload, ... readonly
- #context_object ⇒ Upload, ... readonly
- #controller_path ⇒ Upload, ... readonly
- #disable_delete ⇒ Upload, ... readonly
- #parent_form_id ⇒ Upload, ... readonly
- #upload ⇒ Upload, ... readonly
Instance Method Summary collapse
-
#attachment_name ⇒ String
Human-readable attachment name.
-
#download_link ⇒ String
URL for the download link.
-
#fancybox_group ⇒ String
Fancybox group name; unique per upload to prevent gallery behavior.
-
#fancybox_type ⇒ String
Fancybox content type derived from the upload's MIME type.
-
#file_size ⇒ String
Human-readable file size.
-
#hidden_field_tag_html ⇒ ActiveSupport::SafeBuffer
Hidden +upload_ids[]+ field linking this upload to the context's form.
-
#image_url ⇒ String?
Thumbnail URL for the card image, or +nil+ for non-thumbnailable files.
-
#initialize(upload:, context_object: nil, context_class: nil, controller_path: nil, disable_delete: false, parent_form_id: nil) ⇒ UploadCardComponent
constructor
A new instance of UploadCardComponent.
-
#preview_url ⇒ String
URL for the Fancybox preview link.
-
#remove_button ⇒ ActiveSupport::SafeBuffer
Remove button linking to the context controller's +remove_attachment+ action.
Constructor Details
#initialize(upload:, context_object: nil, context_class: nil, controller_path: nil, disable_delete: false, parent_form_id: nil) ⇒ UploadCardComponent
Returns a new instance of UploadCardComponent.
27 28 29 30 31 32 33 34 35 36 37 |
# File 'app/components/crm/upload_card_component.rb', line 27 def initialize(upload:, context_object: nil, context_class: nil, controller_path: nil, disable_delete: false, parent_form_id: nil) super() @upload = upload @context_object = context_object @context_class = context_class || context_object&.class raise ArgumentError, 'context_class is required when context_object is nil' if @context_class.nil? @controller_path = controller_path || (@context_class.is_a?(Class) ? @context_class.name.tableize : @context_class.to_s.tableize) @disable_delete = disable_delete @parent_form_id = parent_form_id end |
Instance Attribute Details
#context_class ⇒ Upload, ... (readonly)
15 16 17 |
# File 'app/components/crm/upload_card_component.rb', line 15 def context_class @context_class end |
#context_object ⇒ Upload, ... (readonly)
15 16 17 |
# File 'app/components/crm/upload_card_component.rb', line 15 def context_object @context_object end |
#controller_path ⇒ Upload, ... (readonly)
15 16 17 |
# File 'app/components/crm/upload_card_component.rb', line 15 def controller_path @controller_path end |
#disable_delete ⇒ Upload, ... (readonly)
15 16 17 |
# File 'app/components/crm/upload_card_component.rb', line 15 def disable_delete @disable_delete end |
#parent_form_id ⇒ Upload, ... (readonly)
15 16 17 |
# File 'app/components/crm/upload_card_component.rb', line 15 def parent_form_id @parent_form_id end |
#upload ⇒ Upload, ... (readonly)
15 16 17 |
# File 'app/components/crm/upload_card_component.rb', line 15 def upload @upload end |
Instance Method Details
#attachment_name ⇒ String
Human-readable attachment name.
80 81 82 |
# File 'app/components/crm/upload_card_component.rb', line 80 def helpers.(upload) end |
#download_link ⇒ String
URL for the download link.
100 101 102 |
# File 'app/components/crm/upload_card_component.rb', line 100 def download_link helpers.upload_path(upload) end |
#fancybox_group ⇒ String
Fancybox group name; unique per upload to prevent gallery behavior.
121 122 123 |
# File 'app/components/crm/upload_card_component.rb', line 121 def fancybox_group "upload-#{upload.id}" end |
#fancybox_type ⇒ String
Fancybox content type derived from the upload's MIME type.
106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'app/components/crm/upload_card_component.rb', line 106 def fancybox_type # Use cached mime_type from database (fast) instead of attachment.mime_type # which can trigger network calls mime = upload. || upload.mime_type if mime&.start_with?('image') 'image' elsif mime == 'application/pdf' 'pdf' else 'iframe' end end |
#file_size ⇒ String
Human-readable file size.
86 87 88 |
# File 'app/components/crm/upload_card_component.rb', line 86 def file_size helpers.number_to_human_size(upload.) end |
#hidden_field_tag_html ⇒ ActiveSupport::SafeBuffer
Hidden +upload_ids[]+ field linking this upload to the context's form.
41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'app/components/crm/upload_card_component.rb', line 41 def hidden_field_tag_html # Handle both Class and String inputs for context_class class_name = context_class.is_a?(String) ? context_class : context_class.name param_name = "#{class_name.tableize.singularize}[upload_ids][]" # If parent_form_id is specified, associate the hidden field with that form if parent_form_id.present? helpers.hidden_field_tag param_name, upload.id, form: parent_form_id else helpers.hidden_field_tag param_name, upload.id end end |
#image_url ⇒ String?
Thumbnail URL for the card image, or +nil+ for non-thumbnailable files.
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'app/components/crm/upload_card_component.rb', line 56 def image_url # For publications: use ImageKit CDN cover image (fast, no network calls) # For images: use presigned URL directly (browser scales, no Dragonfly processing) # For PDFs: use Dragonfly/libvips generated thumbnail # For other files: no thumbnail if upload.publication upload.publication.cover_image_url(width: 400) elsif upload.is_image? # Use presigned URL directly - browser can display and scale the image # This avoids slow Dragonfly thumbnail generation upload.presigned_url(expires_in: 6.days) elsif upload.is_pdf? # Use Dragonfly libvips for PDF thumbnail generation (first page) upload.thumbnail_url(dimensions: '300x300>') else nil # Skip for non-thumbnailable files (e.g., .doc, .xls) end rescue StandardError => e Rails.logger.debug { "[UploadCardComponent] image_url error: #{e.}" } nil end |
#preview_url ⇒ String
URL for the Fancybox preview link.
92 93 94 95 96 |
# File 'app/components/crm/upload_card_component.rb', line 92 def preview_url # Use local presigned URL generation (fast, no S3 network call) # No fallback to slow remote_url - if presigned fails, link will be broken but page loads fast upload.presigned_url(expires_in: 6.days) end |
#remove_button ⇒ ActiveSupport::SafeBuffer
Remove button linking to the context controller's +remove_attachment+ action.
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'app/components/crm/upload_card_component.rb', line 127 def # Use controller_path explicitly for route generation # This handles irregular controllers (e.g., article_trainings vs Article model) remove_params = { upload_id: upload.id, context_object_id: context_object&.id || 0, context_class: context_class.name, format: :turbo_stream } # Use url_for with explicit controller_path for route generation remove_url = helpers.url_for(controller: controller_path, action: :remove_attachment, **remove_params, only_path: true) helpers.link_to( remove_url, class: 'btn btn-sm btn-outline-danger w-100', 'aria-label': "Remove #{}", data: { turbo_method: :delete, turbo_stream: true, turbo_confirm: 'Are you sure you want to delete this attachment?' } ) do fa_icon('trash', text: 'Remove') end end |