Class: Ace::Task::Molecules::TaskDisplayFormatter

Inherits:
Object
  • Object
show all
Defined in:
lib/ace/task/molecules/task_display_formatter.rb

Overview

Formats task objects for terminal display. Handles single-task show output and compact list output, including subtask tree rendering.

Constant Summary collapse

STATUS_SYMBOLS =
{
  "pending" => "",
  "in-progress" => "",
  "done" => "",
  "blocked" => "",
  "draft" => "",
  "skipped" => "",
  "cancelled" => ""
}.freeze
STATUS_COLORS =
{
  "pending" => nil,
  "in-progress" => Ace::Support::Items::Atoms::AnsiColors::YELLOW,
  "done" => Ace::Support::Items::Atoms::AnsiColors::GREEN,
  "blocked" => Ace::Support::Items::Atoms::AnsiColors::RED,
  "draft" => Ace::Support::Items::Atoms::AnsiColors::CYAN,
  "skipped" => Ace::Support::Items::Atoms::AnsiColors::DIM,
  "cancelled" => Ace::Support::Items::Atoms::AnsiColors::DIM
}.freeze
PRIORITY_LABELS =
{
  "critical" => "",
  "high" => "",
  "medium" => "",
  "low" => ""
}.freeze
PRIORITY_COLORS =
{
  "critical" => Ace::Support::Items::Atoms::AnsiColors::RED,
  "low" => Ace::Support::Items::Atoms::AnsiColors::DIM
}.freeze
STATUS_ORDER =
%w[draft pending in-progress done blocked skipped cancelled].freeze

Class Method Summary collapse

Class Method Details

.format(task, show_content: false) ⇒ String

Format a single task for detailed display (show command).

Parameters:

  • task (Models::Task)

    Task to format

  • show_content (Boolean) (defaults to: false)

    Whether to include body content

Returns:

  • (String)

    Formatted output



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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/ace/task/molecules/task_display_formatter.rb', line 57

def self.format(task, show_content: false)
  lines = []

  # Header line: status symbol, ID, title
  status_sym = colored_status_sym(task.status)
  priority_sym = PRIORITY_LABELS[task.priority] || ""
  priority_prefix = priority_sym.empty? ? "" : "#{priority_sym} "
  lines << "#{status_sym} #{priority_prefix}#{task.id}  #{task.title}"

  # Metadata line
  meta_parts = []
  meta_parts << "status: #{task.status}"
  meta_parts << "priority: #{task.priority}" if task.priority
  meta_parts << "estimate: #{task.estimate}" if task.estimate
  lines << "  #{meta_parts.join("  |  ")}"

  # Tags
  if task.tags && task.tags.any?
    lines << "  tags: #{task.tags.join(", ")}"
  end

  # Dependencies
  if task.dependencies && task.dependencies.any?
    lines << "  depends: #{task.dependencies.join(", ")}"
  end

  # Folder info
  if task.special_folder
    lines << "  folder: #{task.special_folder}"
  end

  # Parent info for subtasks
  if task.parent_id
    lines << "  parent: #{task.parent_id}"
  end

  # Subtasks
  if task.has_subtasks?
    lines << ""
    lines << "  Subtasks:"
    task.subtasks.each do |st|
      st_sym = colored_status_sym(st.status)
      lines << "    #{st_sym} #{st.id}  #{st.title}"
    end
  end

  # Body content
  if show_content && task.content && !task.content.strip.empty?
    lines << ""
    lines << task.content.strip
  end

  lines.join("\n")
end

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

Format a list of tasks for compact display (list command).

Parameters:

  • tasks (Array<Models::Task>)

    Tasks 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



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/ace/task/molecules/task_display_formatter.rb', line 117

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

  body = if tasks.empty?
    "No tasks found."
  else
    tasks.map { |task| format_list_item(task) }.join("\n")
  end

  "#{body}\n\n#{stats_line}"
end

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

Format a stats summary line for a list of tasks.

Parameters:

  • tasks (Array<Models::Task>)

    Tasks 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. “Tasks: ○ 2 | ▶ 1 | ✓ 5 • 3 of 660”



159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/ace/task/molecules/task_display_formatter.rb', line 159

def self.format_stats_line(tasks, total_count: nil, global_folder_stats: nil)
  stats = Ace::Support::Items::Atoms::ItemStatistics.count_by(tasks, :status)
  folder_stats = Ace::Support::Items::Atoms::ItemStatistics.count_by(tasks, :special_folder)
  Ace::Support::Items::Atoms::StatsLineFormatter.format(
    label: "Tasks",
    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_tasks:) ⇒ String

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

Parameters:

  • categorized (Hash)

    Output of StatusCategorizer.categorize

  • all_tasks (Array<Models::Task>)

    All tasks for stats computation

Returns:

  • (String)

    Formatted status output



139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/ace/task/molecules/task_display_formatter.rb', line 139

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

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

  # Stats summary
  sections << format_stats_line(all_tasks)

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

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

.format_status_line(task) ⇒ String

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

Parameters:

Returns:

  • (String)

    e.g. “ ○ 8pp.t.q7w Fix login bug”



176
177
178
179
# File 'lib/ace/task/molecules/task_display_formatter.rb', line 176

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