Module: Crm::ImagesHelper

Defined in:
app/helpers/crm/images_helper.rb

Instance Method Summary collapse

Instance Method Details

#image_command_options(image = @image) ⇒ Object



2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# File 'app/helpers/crm/images_helper.rb', line 2

def image_command_options(image = @image)
  [].tap do |links|
    links << link_to(fa_icon('wrench', text: 'Edit Image'), edit_image_path(image.id)) if can?(:update, image)
    links << link_to(fa_icon('wrench', text: 'Edit Image Profiles'), edit_image_profiles_image_path(@image)) if can?(:update, image)
    links << link_to(fa_icon('crop', text: 'Transform'), transform_image_path(image))
    links << link_to(fa_icon('clone', text: 'Clone Image'), clone_image_path(image.id), data: { turbo_method: :post }) if can?(:create, Image)
    links << link_to(fa_icon('broom', text: 'Purge Cache'), purge_cache_image_path(image), data: { turbo_method: :post })
    links << link_to(fa_icon('image', text: 'Make Primary Image of Items'), make_primary_item_image_image_path(image), data: { turbo_method: :post })
    # AI Upscale - always available for users who can update images
    links << link_to(fa_icon('expand', text: 'Upscale Image'), upscale_preview_image_path(image)) if can?(:update, image)
    # AI Generation - generate a variation of this image
    if can?(:update, image) && ImageGeneration::Service.available?
      links << link_to(fa_icon('wand-magic-sparkles', text: 'Generate Variation'), new_generated_image_path(source_image_id: image.id))
    end
    # Find Similar - only show if image has visual embedding
    links << link_to(fa_icon('images', text: 'Find Similar Images'), find_similar_image_path(image)) if image_has_visual_embedding?(image)
    links << link_to(fa_icon('trash', text: 'Delete'), image_path(image), data: { turbo_method: :delete, turbo_confirm: 'Are you sure?' }) if can?(:destroy, image)
  end
end

#image_download_options(image = @image) ⇒ Object



28
29
30
31
32
33
34
35
36
37
# File 'app/helpers/crm/images_helper.rb', line 28

def image_download_options(image = @image)
  copy_link = tag.a(fa_icon('copy', text: 'Copy URL'),
                    href: '#',
                    data: { controller: 'clipboard',
                            clipboard_text_value: image.image_url,
                            action: 'click->clipboard#copy' })
  encode_formats = [image.attachment_format&.to_sym, :png, :jpeg, :webp, :avif, :tiff].compact.uniq
  download_links = encode_formats.map { |encode_format| link_to(fa_icon('download', text: "Download #{encode_format.to_s.upcase}"), image.image_url(encode_format:, download: true)) }
  [copy_link] + download_links
end

#image_has_visual_embedding?(image) ⇒ Boolean

Check if image has a unified embedding for visual similarity search

Returns:

  • (Boolean)


23
24
25
26
# File 'app/helpers/crm/images_helper.rb', line 23

def image_has_visual_embedding?(image)
  unified = image.find_content_embedding(:unified)
  unified&.unified_embedding.present?
end

#image_info(image) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
# File 'app/helpers/crm/images_helper.rb', line 43

def image_info(image)
  [
    "Title: #{image.title}",
    "Slug: #{image.slug}",
    "Dimensions: #{image.dimensions}",

    "Position: #{image.position}",
    "Tags: #{image.tags.join(', ')}",
    "Locales: #{image.locales&.join(', ')}"
  ].join("\n")
end

#item_image_command_options(item:, image:, return_path: nil) ⇒ Object



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/images_helper.rb', line 55

def item_image_command_options(item:, image:, return_path: nil)
  return_path ||= item_path(item.id, tab: 'images')
  [].tap do |links|
    links << link_to('View Image', image_path(image, return_path: return_path), data: { turbo_frame: '_top' })
    links << link_to('Edit Image', edit_image_path(image, return_path: return_path), target: :_blank, rel: :noopener)

    if item && can?(:manage, item)
      images_return_path = item_path(item.id, tab: 'images', tag: @selected_tag, image_locale: @image_locale)
      links << if item.primary_image_id == image.id
                 link_to('Change Item Primary Image', edit_item_path(item, section: 'images', return_path: images_return_path))
               else
                 link_to('Make Primary Image of Item', make_primary_image_item_path(item, image_id: image.id, return_path: images_return_path), data: { turbo_method: :post })
               end

      # Count how many slots this image already covers (summary badge in the label)
      assigned_count = @image_profile_types_by_image_id&.dig(image.id)&.size || 0
      label = assigned_count > 0 ? "Assign to Slots... (#{assigned_count} ✓)" : 'Assign to Slots...'
      dialog_url = slot_assignment_dialog_image_profile_manager_path(item, image_id: image.id, content_locale: 'en')

      links << link_to(label, '#',
                       data: {
                         controller: 'dialog-trigger',
                         action: 'click->dialog-trigger#open',
                         dialog_trigger_dialog_value: 'imageProfileDialog',
                         dialog_trigger_src_value: dialog_url
                       })
    end
  end
end

#panel_title_with_badge(title, count) ⇒ Object



39
40
41
# File 'app/helpers/crm/images_helper.rb', line 39

def panel_title_with_badge(title, count)
  "#{title} <span class='badge bg-secondary ms-1'>#{count}</span>"
end