Class: Ace::Support::Items::Atoms::StatsLineFormatter

Inherits:
Object
  • Object
show all
Defined in:
lib/ace/support/items/atoms/stats_line_formatter.rb

Overview

Generic stats line builder for item lists. Produces a summary like: “Tasks: ○ 3 | ▶ 1 | ✓ 5 • 3 of 660”

Class Method Summary collapse

Class Method Details

.format(label:, stats:, status_order:, status_icons:, folder_stats: nil, total_count: nil, global_folder_stats: nil) ⇒ String

Returns e.g. “Tasks: ○ 3 | ▶ 1 | ✓ 5 • 3 of 660”.

Parameters:

  • label (String)

    e.g. “Tasks”, “Ideas”, “Retros”

  • stats (Hash)

    Output of ItemStatistics.count_by (by :status)

  • status_order (Array<String>)

    Ordered status keys to display

  • status_icons (Hash<String,String>)

    Status → icon mapping

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

    Output of ItemStatistics.count_by (by :special_folder)

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

    Total items before folder filtering (enables “X of Y” display)

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

    Folder name → count hash from full scan (always shown)

Returns:

  • (String)

    e.g. “Tasks: ○ 3 | ▶ 1 | ✓ 5 • 3 of 660”



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/ace/support/items/atoms/stats_line_formatter.rb', line 20

def self.format(label:, stats:, status_order:, status_icons:, folder_stats: nil, total_count: nil, global_folder_stats: nil)
  parts = []
  status_order.each do |status|
    count = stats[:by_field][status] || 0
    next if count == 0

    icon = status_icons[status] || status
    parts << "#{icon} #{count}"
  end

  # Catch any statuses not in status_order (unknown/unexpected)
  stats[:by_field].each do |status, count|
    next if count == 0 || status_order.include?(status)

    icon = status_icons[status] || status
    parts << "#{icon} #{count}"
  end

  line = if parts.empty?
    "#{label}:"
  else
    "#{label}: #{parts.join(" | ")}"
  end

  shown = stats[:total]
  total = total_count || shown

  if shown < total
    # Filtered view: show ratio
    line += " \u2022 #{shown} of #{total}"
  else
    # Full view: show total
    line += " \u2022 #{shown} total"
    # Inline folder breakdown from current results (only when unfiltered
    # and global_folder_stats not provided — global takes precedence)
    if !global_folder_stats && folder_stats && folder_stats[:by_field].size > 1
      folder_parts = folder_stats[:by_field]
        .sort_by { |_, count| -count }
        .map { |folder, count| "#{folder_label(folder)} #{count}" }
      suffix = " \u2014 #{folder_parts.join(" | ")}"
      line += AnsiColors.colorize(suffix, AnsiColors::DIM)
    end
  end

  # Global folder breakdown (always shown when provided and multi-folder)
  if global_folder_stats && global_folder_stats.size > 1
    global_parts = global_folder_stats
      .sort_by { |_, count| -count }
      .map { |folder, count| "#{folder_label(folder)} #{count}" }
    suffix = " \u2014 #{global_parts.join(" | ")}"
    line += AnsiColors.colorize(suffix, AnsiColors::DIM)
  end

  line
end