Class: Ace::Idea::Molecules::IdeaDisplayFormatter

Inherits:
Object
  • Object
show all
Defined in:
lib/ace/idea/molecules/idea_display_formatter.rb

Overview

Formats idea objects for terminal display.

Constant Summary collapse

STATUS_SYMBOLS =
{
  "pending" => "",
  "in-progress" => "",
  "done" => "",
  "obsolete" => ""
}.freeze
STATUS_COLORS =
{
  "pending" => nil,
  "in-progress" => Ace::Support::Items::Atoms::AnsiColors::YELLOW,
  "done" => Ace::Support::Items::Atoms::AnsiColors::GREEN,
  "obsolete" => Ace::Support::Items::Atoms::AnsiColors::DIM
}.freeze
STATUS_ORDER =
%w[pending in-progress done obsolete].freeze

Class Method Summary collapse

Class Method Details

.format(idea, show_content: false) ⇒ String

Format a single idea for display

Parameters:

  • idea (Idea)

    Idea to format

  • show_content (Boolean) (defaults to: false)

    Whether to include full content

Returns:

  • (String)

    Formatted output



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/ace/idea/molecules/idea_display_formatter.rb', line 45

def self.format(idea, show_content: false)
  c = Ace::Support::Items::Atoms::AnsiColors
  status_sym = colored_status_sym(idea.status)
  id_str = show_content ? idea.id : c.colorize(idea.id, c::DIM)
  tags_str = idea.tags.any? ? c.colorize(" [#{idea.tags.join(", ")}]", c::DIM) : ""
  folder_str = idea.special_folder ? c.colorize(" (#{idea.special_folder})", c::DIM) : ""

  lines = []
  lines << "#{status_sym} #{id_str} #{idea.title}#{tags_str}#{folder_str}"

  if show_content && idea.content && !idea.content.strip.empty?
    lines << ""
    lines << idea.content
  end

  if show_content && idea.attachments.any?
    lines << ""
    lines << "Attachments: #{idea.attachments.join(", ")}"
  end

  lines.join("\n")
end

.format_list(ideas, total_count: nil, global_folder_stats: nil) ⇒ String

Format a list of ideas for display

Parameters:

  • ideas (Array<Idea>)

    Ideas to format

  • total_count (Integer, nil) (defaults to: nil)

    Total items before folder filtering

  • global_folder_stats (Hash, nil) (defaults to: nil)

    Folder name → count hash from full scan

Returns:

  • (String)

    Formatted list output



73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/ace/idea/molecules/idea_display_formatter.rb', line 73

def self.format_list(ideas, total_count: nil, global_folder_stats: nil)
  stats_line = format_stats_line(
    ideas,
    total_count: total_count,
    global_folder_stats: global_folder_stats
  )

  if ideas.empty?
    "No ideas found.\n\n#{stats_line}"
  else
    "#{ideas.map { |idea| format(idea) }.join("\n")}\n\n#{stats_line}"
  end
end

.format_stats_line(ideas, total_count: nil, global_folder_stats: nil) ⇒ String

Format a stats summary line for a list of ideas.

Parameters:

  • ideas (Array<Idea>)

    Ideas to summarize

  • total_count (Integer, nil) (defaults to: nil)

    Total items before folder filtering

  • global_folder_stats (Hash, nil) (defaults to: nil)

    Folder name → count hash from full scan

Returns:

  • (String)

    e.g. “Ideas: ○ 3 | ▶ 1 | ✓ 2 • 3 of 8”



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/ace/idea/molecules/idea_display_formatter.rb', line 121

def self.format_stats_line(ideas, total_count: nil, global_folder_stats: nil)
  stats = {total: ideas.size, by_field: Hash.new(0)}
  folder_stats = {total: ideas.size, by_field: Hash.new(0)}

  ideas.each do |idea|
    stats[:by_field][normalize_status(idea.status)] += 1
    folder_stats[:by_field][idea.special_folder] += 1
  end

  Ace::Support::Items::Atoms::StatsLineFormatter.format(
    label: "Ideas",
    stats: stats,
    status_order: STATUS_ORDER,
    status_icons: STATUS_SYMBOLS,
    folder_stats: folder_stats,
    total_count: total_count,
    global_folder_stats: global_folder_stats
  )
end

.format_status(categorized, all_ideas:) ⇒ String

Format a status overview with up-next, stats, and recently-done sections.

Parameters:

  • categorized (Hash)

    Output of StatusCategorizer.categorize

  • all_ideas (Array<Idea>)

    All ideas for stats computation

Returns:

  • (String)

    Formatted status output



93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/ace/idea/molecules/idea_display_formatter.rb', line 93

def self.format_status(categorized, all_ideas:)
  sections = []

  # Up Next
  sections << format_up_next_section(categorized[:up_next])

  # Stats summary
  sections << format_stats_line(all_ideas)

  # Recently Done
  sections << format_recently_done_section(categorized[:recently_done])

  sections.join("\n\n")
end

.format_status_line(idea) ⇒ String

Format a single idea as a compact status line (id + title only).

Parameters:

  • idea (Idea)

    Idea to format

Returns:

  • (String)

    e.g. “ ⚪ 8ppq7w Dark mode support”



111
112
113
114
# File 'lib/ace/idea/molecules/idea_display_formatter.rb', line 111

def self.format_status_line(idea)
  status_sym = colored_status_sym(idea.status)
  "  #{status_sym} #{idea.id}  #{idea.title}"
end