Spaces:
Running
Running
File size: 4,717 Bytes
fae4e5b |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 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 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 111 112 113 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 158 159 |
"""
Navigation utilities for MockTraceMind screen flow
"""
import gradio as gr
from enum import Enum
from typing import Dict, Any, Tuple
class Screen(Enum):
"""Available screens in MockTraceMind"""
LEADERBOARD = "leaderboard"
COMPARE = "compare"
RUN_DETAIL = "run_detail"
TRACE_DETAIL = "trace_detail"
class Navigator:
"""
Manages screen navigation and state
Screen Flow:
- Leaderboard (Screen 1)
- Click row → Run Detail (Screen 3)
- Select 2+ rows + Compare → Compare View (Screen 2)
- Click either run → Run Detail (Screen 3)
- Run Detail (Screen 3)
- Click test case row → Trace Detail (Screen 4)
- Trace Detail (Screen 4)
- Back → Run Detail (Screen 3)
"""
def __init__(self):
self.current_screen = Screen.LEADERBOARD
self.navigation_stack = [Screen.LEADERBOARD]
self.screen_context: Dict[str, Any] = {}
def navigate_to(
self,
screen: Screen,
context: Dict[str, Any] = None,
add_to_stack: bool = True
) -> Tuple[Screen, Dict[str, Any]]:
"""
Navigate to a screen with optional context
Args:
screen: Target screen
context: Data to pass to the screen
add_to_stack: Whether to add to navigation stack
Returns:
Tuple of (screen, context)
"""
self.current_screen = screen
if context:
self.screen_context.update(context)
if add_to_stack:
self.navigation_stack.append(screen)
return screen, self.screen_context
def back(self) -> Tuple[Screen, Dict[str, Any]]:
"""
Navigate back in the navigation stack
Returns:
Tuple of (previous_screen, context)
"""
if len(self.navigation_stack) > 1:
self.navigation_stack.pop() # Remove current
previous = self.navigation_stack[-1]
self.current_screen = previous
return previous, self.screen_context
# Already at root
return self.current_screen, self.screen_context
def get_current_screen(self) -> Screen:
"""Get current active screen"""
return self.current_screen
def get_context(self, key: str, default: Any = None) -> Any:
"""Get value from screen context"""
return self.screen_context.get(key, default)
def set_context(self, key: str, value: Any) -> None:
"""Set value in screen context"""
self.screen_context[key] = value
def clear_context(self) -> None:
"""Clear all screen context"""
self.screen_context.clear()
def reset(self) -> None:
"""Reset navigation to initial state"""
self.current_screen = Screen.LEADERBOARD
self.navigation_stack = [Screen.LEADERBOARD]
self.screen_context.clear()
# Gradio visibility update helpers
def show_screen(screen: Screen) -> Dict[gr.Component, gr.update]:
"""
Generate Gradio updates to show specific screen
Returns:
Dictionary of component updates for gr.update
"""
return {
"leaderboard_container": gr.update(visible=(screen == Screen.LEADERBOARD)),
"compare_container": gr.update(visible=(screen == Screen.COMPARE)),
"run_detail_container": gr.update(visible=(screen == Screen.RUN_DETAIL)),
"trace_detail_container": gr.update(visible=(screen == Screen.TRACE_DETAIL)),
}
def create_back_button(visible: bool = True) -> gr.Button:
"""Create a consistent back button"""
return gr.Button("⬅️ Back", visible=visible, variant="secondary", size="sm")
def create_breadcrumb(navigation_stack: list) -> str:
"""
Create breadcrumb navigation HTML
Args:
navigation_stack: List of Screen enums
Returns:
HTML string for breadcrumb
"""
breadcrumb_names = {
Screen.LEADERBOARD: "Leaderboard",
Screen.COMPARE: "Compare",
Screen.RUN_DETAIL: "Run Detail",
Screen.TRACE_DETAIL: "Trace Detail"
}
breadcrumb_items = []
for i, screen in enumerate(navigation_stack):
name = breadcrumb_names.get(screen, screen.value)
if i < len(navigation_stack) - 1:
# Not the last item - make it a link
breadcrumb_items.append(f'<span style="color: #666;">{name}</span>')
else:
# Last item - current screen
breadcrumb_items.append(f'<strong>{name}</strong>')
breadcrumb_html = " > ".join(breadcrumb_items)
return f"""
<div style="padding: 10px; background-color: #f5f5f5; border-radius: 5px; margin-bottom: 10px;">
{breadcrumb_html}
</div>
"""
|