Class: Aidp::Harness::UI::Navigation::MainMenu

Inherits:
Base
  • Object
show all
Defined in:
lib/aidp/harness/ui/navigation/main_menu.rb

Overview

Main hierarchical navigation menu system

Direct Known Subclasses

SubMenu

Defined Under Namespace

Classes: InvalidMenuError, MenuError, NavigationError

Instance Method Summary collapse

Constructor Details

#initialize(ui_components = {}, prompt: nil) ⇒ MainMenu

Returns a new instance of MainMenu.



22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/aidp/harness/ui/navigation/main_menu.rb', line 22

def initialize(ui_components = {}, prompt: nil)
  super()
  @prompt = prompt || ui_components[:prompt] || TTY::Prompt.new
  @pastel = Pastel.new
  @formatter = ui_components[:formatter] || MenuFormatter.new
  @state_manager = ui_components[:state_manager] || MenuState.new
  @output = ui_components[:output]
  @menu_items = []
  @current_level = 0
  @breadcrumb = []
  @navigation_history = [] # Track all navigation actions
end

Instance Method Details

#add_menu_item(item) ⇒ Object



35
36
37
38
# File 'lib/aidp/harness/ui/navigation/main_menu.rb', line 35

def add_menu_item(item)
  validate_menu_item(item)
  @menu_items << item
end

#add_menu_items(items) ⇒ Object



40
41
42
43
# File 'lib/aidp/harness/ui/navigation/main_menu.rb', line 40

def add_menu_items(items)
  validate_menu_items(items)
  items.each { |item| add_menu_item(item) }
end

#at_root?Boolean

Returns:

  • (Boolean)


195
196
197
# File 'lib/aidp/harness/ui/navigation/main_menu.rb', line 195

def at_root?
  @breadcrumb.empty?
end

#can_navigate_back?Boolean

Returns:

  • (Boolean)


219
220
221
# File 'lib/aidp/harness/ui/navigation/main_menu.rb', line 219

def can_navigate_back?
  !@breadcrumb.empty?
end

#clear_navigation_historyObject



189
190
191
192
193
# File 'lib/aidp/harness/ui/navigation/main_menu.rb', line 189

def clear_navigation_history
  @breadcrumb.clear
  @current_level = 0
  @navigation_history.clear
end

#current_pathObject



105
106
107
# File 'lib/aidp/harness/ui/navigation/main_menu.rb', line 105

def current_path
  @breadcrumb.join(" > ")
end

#current_sectionObject

Additional methods expected by tests



207
208
209
# File 'lib/aidp/harness/ui/navigation/main_menu.rb', line 207

def current_section
  @breadcrumb.last || "Home"
end

#display_breadcrumbObject

Make display_breadcrumb public for testing



224
225
226
227
228
229
230
231
# File 'lib/aidp/harness/ui/navigation/main_menu.rb', line 224

def display_breadcrumb
  if @breadcrumb.empty?
    display_message "Home"
  else
    breadcrumb_text = @formatter.format_breadcrumb(@breadcrumb)
    display_message(breadcrumb_text)
  end
end

#display_menu(title, menu_items) ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/aidp/harness/ui/navigation/main_menu.rb', line 60

def display_menu(title, menu_items)
  # Handle nil title case
  title = "Main Menu" if title.nil?
  validate_title(title)
  validate_menu_items(menu_items)

  # Set the menu items for display
  @menu_items = menu_items

  display_menu_header(title)
  display_breadcrumb
  display_menu_items

  # Add navigation instructions if items exist
  if menu_items.any?
    display_message "Use arrow keys to navigate, Enter to select"
  else
    display_message "No options available"
  end
rescue => e
  raise NavigationError, "Failed to display menu: #{e.message}"
end

#display_navigation_helpObject



199
200
201
202
203
204
# File 'lib/aidp/harness/ui/navigation/main_menu.rb', line 199

def display_navigation_help
  display_message "Navigation Help"
  display_message "Use arrow keys to navigate"
  display_message "Press Enter to select"
  display_message "Press Escape to go back"
end

#get_breadcrumb_pathObject



211
212
213
# File 'lib/aidp/harness/ui/navigation/main_menu.rb', line 211

def get_breadcrumb_path
  ["Home"] + @breadcrumb
end

#get_navigation_historyObject



184
185
186
187
# File 'lib/aidp/harness/ui/navigation/main_menu.rb', line 184

def get_navigation_history
  # Return the complete navigation history
  @navigation_history
end

#get_user_input(prompt) ⇒ Object



159
160
161
162
# File 'lib/aidp/harness/ui/navigation/main_menu.rb', line 159

def get_user_input(prompt)
  # Mock method for testing - will be stubbed in tests
  @prompt.ask(prompt)
end

#go_backObject



97
98
99
100
101
102
103
# File 'lib/aidp/harness/ui/navigation/main_menu.rb', line 97

def go_back
  return false if @breadcrumb.empty?

  @breadcrumb.pop
  @current_level -= 1
  true
end


109
110
111
# File 'lib/aidp/harness/ui/navigation/main_menu.rb', line 109

def menu_depth
  @current_level
end


170
171
172
173
174
175
176
177
# File 'lib/aidp/harness/ui/navigation/main_menu.rb', line 170

def navigate_back
  return false if @breadcrumb.empty?

  section = @breadcrumb.pop
  @current_level -= 1
  @navigation_history << {action: :navigate_back, section: section}
  true
end


164
165
166
167
168
# File 'lib/aidp/harness/ui/navigation/main_menu.rb', line 164

def navigate_to(section_name)
  @breadcrumb << section_name
  @current_level += 1
  @navigation_history << {action: :navigate_to, section: section_name}
end


179
180
181
182
# File 'lib/aidp/harness/ui/navigation/main_menu.rb', line 179

def navigate_to_root
  @breadcrumb.clear
  @current_level = 0
end


83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/aidp/harness/ui/navigation/main_menu.rb', line 83

def navigate_to_submenu(submenu_title)
  validate_title(submenu_title)

  submenu = find_submenu(submenu_title)
  raise InvalidMenuError, "Submenu '#{submenu_title}' not found" unless submenu

  @breadcrumb << submenu_title
  @current_level += 1

  submenu.show_menu(submenu_title)
rescue => e
  raise NavigationError, "Failed to navigate to submenu: #{e.message}"
end


215
216
217
# File 'lib/aidp/harness/ui/navigation/main_menu.rb', line 215

def navigation_depth
  @current_level
end

#select_option(menu_items) ⇒ Object

Methods expected by tests



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/aidp/harness/ui/navigation/main_menu.rb', line 114

def select_option(menu_items)
  @menu_items = menu_items
  display_menu_items

  max_attempts = 10 # Prevent infinite loops
  attempts = 0

  loop do
    attempts += 1
    break if attempts > max_attempts

    # Use get_user_input for testing compatibility
    input = get_user_input("Select an option: ")

    # Handle cancel/quit
    if input.downcase == "q" || input.downcase == "quit" || input.downcase == "cancel"
      return nil
    end

    # Handle numeric input
    if input.match?(/^\d+$/)
      index = input.to_i - 1
      if index >= 0 && index < menu_items.length
        return menu_items[index]
      else
        display_message "Invalid selection"
        next
      end
    else
      # Handle text input
      selected_item = menu_items.find { |item| item.title.downcase == input.downcase }
      if selected_item
        return selected_item
      else
        display_message "Invalid selection"
        next
      end
    end
  end

  # If we get here, we've exceeded max attempts
  display_message "Too many invalid attempts. Returning first option."
  menu_items.first
end

#show_menu(title = "Main Menu") ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/aidp/harness/ui/navigation/main_menu.rb', line 45

def show_menu(title = "Main Menu")
  validate_title(title)

  loop do
    display_menu_header(title)
    display_breadcrumb
    display_menu_items

    selection = prompt_for_selection
    break if handle_selection(selection) == :exit
  end
rescue => e
  raise NavigationError, "Failed to show menu: #{e.message}"
end