Skip to content

Commit 099f564

Browse files
committed
Fix recent_activity (extract image helper and add decorator)
1 parent 3f920ad commit 099f564

File tree

4 files changed

+106
-92
lines changed

4 files changed

+106
-92
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
class ProjectUserDecorator < Draper::Decorator
2+
delegate_all
3+
4+
5+
def description
6+
"#{user.full_name}: #{title.presence || position} - #{project.name}"
7+
end
8+
end

app/helpers/application_helper.rb

Lines changed: 0 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -49,46 +49,6 @@ def display_banner
4949
end
5050
end
5151

52-
def main_image_url(record)
53-
return nil unless record.present?
54-
55-
# All possible attachment names used across your models
56-
attachment_candidates = ["main_image", "avatar", "photo", "banner", "hero_image",
57-
"gallery_images", "images", "attachments", "media_files"]
58-
59-
attachment_candidates.each do |name|
60-
next unless record.respond_to?(name)
61-
62-
value = record.public_send(name)
63-
next if value.blank?
64-
65-
# CASE 1 — Direct ActiveStorage attachment (e.g., user.avatar)
66-
if value.respond_to?(:attached?) && value.attached?
67-
return url_for(value)
68-
end
69-
70-
# CASE 2 — Wrapper Model (e.g., StoryIdea.main_image)
71-
if value.respond_to?(:file) &&
72-
value.file.respond_to?(:attached?) &&
73-
value.file.attached?
74-
75-
return url_for(value.file)
76-
end
77-
78-
# CASE 3 — Collection (e.g., StoryIdea.gallery_images)
79-
# value = ActiveRecord::Associations::CollectionProxy each item is an Image STI instance
80-
if value.is_a?(Enumerable)
81-
img = value.find { |img| img.respond_to?(:file) &&
82-
img.file.respond_to?(:attached?) &&
83-
img.file.attached? }
84-
85-
return url_for(img.file) if img
86-
end
87-
end
88-
89-
nil
90-
end
91-
9252
def ra_path(obj, action = nil)
9353
action = action.nil? ? '' : "#{action}_"
9454

@@ -130,58 +90,6 @@ def sortable_field_display_name(name)
13090
end
13191
end
13292

133-
def title_with_badges(record, font_size: "text-lg", record_title: nil,
134-
show_hidden_badge: false, display_windows_type: false)
135-
fragments = []
136-
137-
# --- Hidden badge ---
138-
if show_hidden_badge && record.respond_to?(:inactive?) &&
139-
record.inactive? && controller_name != "dashboard"
140-
fragments << content_tag(
141-
:span,
142-
content_tag(:i, "", class: "fa-solid fa-eye-slash mr-1") + " Hidden",
143-
class: "inline-flex items-center px-2 py-0.5 rounded-full
144-
text-sm font-medium bg-blue-100 text-gray-600 whitespace-nowrap"
145-
)
146-
end
147-
148-
# --- Featured badge ---
149-
if record.respond_to?(:featured?) && record.featured? && controller_name != "dashboard"
150-
fragments << content_tag(
151-
:span,
152-
"🌟 Dashboard Feature",
153-
class: "inline-flex items-center px-2 py-0.5 rounded-full
154-
text-sm font-medium bg-yellow-100 text-yellow-800 whitespace-nowrap"
155-
)
156-
end
157-
158-
title_content = record_title.presence || record.title.to_s
159-
160-
if display_windows_type && record.respond_to?(:windows_type) && record.windows_type.present?
161-
title_content += " (#{record.windows_type.short_name})"
162-
end
163-
164-
title_row = content_tag(
165-
:span,
166-
title_content.html_safe,
167-
class: "#{font_size} font-semibold text-gray-900 leading-tight"
168-
)
169-
170-
# ---- Combine rows intelligently ----
171-
if fragments.any?
172-
content_tag :div, class: "flex flex-col" do
173-
safe_join([
174-
content_tag(:div, safe_join(fragments), class: "flex flex-wrap items-center gap-2 mb-1"),
175-
title_row
176-
])
177-
end
178-
else
179-
# No badges: just return the title with no empty div wrapper
180-
title_row
181-
end
182-
end
183-
184-
18593
def icon_for_mimetype(mime)
18694
mimes = {
18795
'image' => 'fa-file-image',

app/helpers/image_helper.rb

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
module ImageHelper
2+
3+
def main_image_url(record)
4+
return nil unless record.present?
5+
6+
# All possible attachment names used across your models
7+
attachment_candidates = ["main_image", "avatar", "photo", "banner", "hero_image",
8+
"gallery_images", "images", "attachments", "media_files"]
9+
10+
attachment_candidates.each do |name|
11+
next unless record.respond_to?(name)
12+
13+
value = record.public_send(name)
14+
next if value.blank?
15+
16+
# CASE 1 — Direct ActiveStorage attachment (e.g., user.avatar)
17+
if value.respond_to?(:attached?) && value.attached?
18+
return url_for(value)
19+
end
20+
21+
# CASE 2 — Wrapper Model (e.g., StoryIdea.main_image)
22+
if value.respond_to?(:file) &&
23+
value.file.respond_to?(:attached?) &&
24+
value.file.attached?
25+
26+
return url_for(value.file)
27+
end
28+
29+
# CASE 3 — Collection (e.g., StoryIdea.gallery_images)
30+
# value = ActiveRecord::Associations::CollectionProxy each item is an Image STI instance
31+
if value.is_a?(Enumerable)
32+
img = value.find { |img| img.respond_to?(:file) &&
33+
img.file.respond_to?(:attached?) &&
34+
img.file.attached? }
35+
36+
return url_for(img.file) if img
37+
end
38+
end
39+
40+
nil
41+
end
42+
43+
end
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
module TitleDisplayHelper
2+
3+
def title_with_badges(record, font_size: "text-lg", record_title: nil,
4+
show_hidden_badge: false, display_windows_type: false)
5+
6+
fragments = []
7+
8+
# --- Hidden badge ---
9+
if show_hidden_badge && record.respond_to?(:inactive?) &&
10+
record.inactive? && controller_name != "dashboard"
11+
fragments << content_tag(
12+
:span,
13+
content_tag(:i, "", class: "fa-solid fa-eye-slash mr-1") + " Hidden",
14+
class: "inline-flex items-center px-2 py-0.5 rounded-full
15+
text-sm font-medium bg-blue-100 text-gray-600 whitespace-nowrap"
16+
)
17+
end
18+
19+
# --- Featured badge ---
20+
if record.respond_to?(:featured?) && record.featured? && controller_name != "dashboard"
21+
fragments << content_tag(
22+
:span,
23+
"🌟 Dashboard feature",
24+
class: "inline-flex items-center px-2 py-0.5 rounded-full
25+
text-sm font-medium bg-yellow-100 text-yellow-800 whitespace-nowrap"
26+
)
27+
end
28+
29+
title_content = record_title.presence || record.title.to_s
30+
31+
if display_windows_type && record.respond_to?(:windows_type) && record.windows_type.present?
32+
title_content += " (#{record.windows_type.short_name})"
33+
end
34+
35+
title_row = content_tag(
36+
:span,
37+
title_content.html_safe,
38+
class: "#{font_size} font-semibold text-gray-900 leading-tight"
39+
)
40+
41+
# ---- Combine rows ----
42+
if fragments.any?
43+
content_tag :div, class: "flex flex-col" do
44+
safe_join([
45+
content_tag(:div, safe_join(fragments), class: "flex flex-wrap items-center gap-2 mb-1"),
46+
title_row
47+
])
48+
end
49+
else
50+
title_row
51+
end
52+
end
53+
54+
55+
end

0 commit comments

Comments
 (0)