Coverage for openhcs/textual_tui/services/window_service.py: 0.0%
25 statements
« prev ^ index » next coverage.py v7.10.3, created at 2025-08-14 05:57 +0000
« prev ^ index » next coverage.py v7.10.3, created at 2025-08-14 05:57 +0000
1"""Window service to break circular imports between widgets and windows."""
3from typing import Any, Callable, List, Optional, Type
4from pathlib import Path
5from textual.css.query import NoMatches
7from openhcs.constants.constants import Backend
8from openhcs.textual_tui.services.file_browser_service import SelectionMode
9from openhcs.core.path_cache import PathCacheKey
12class WindowService:
13 """Service to handle window creation and management, breaking circular imports."""
15 def __init__(self, app):
16 self.app = app
18 async def open_file_browser(
19 self,
20 file_manager,
21 initial_path: Path,
22 backend: Backend = Backend.DISK,
23 title: str = "Select Directory",
24 mode: str = "load", # "load" or "save"
25 selection_mode: SelectionMode = SelectionMode.DIRECTORIES_ONLY,
26 filter_extensions: Optional[List[str]] = None,
27 default_filename: str = "",
28 cache_key: Optional[PathCacheKey] = None,
29 on_result_callback: Optional[Callable] = None,
30 caller_id: str = "unknown",
31 enable_multi_selection: bool = False,
32 ):
33 """Open file browser window without circular imports."""
34 # Lazy import to avoid circular dependency
35 from openhcs.textual_tui.windows.file_browser_window import (
36 open_file_browser_window, BrowserMode
37 )
39 browser_mode = BrowserMode.SAVE if mode == "save" else BrowserMode.LOAD
41 return await open_file_browser_window(
42 app=self.app,
43 file_manager=file_manager,
44 initial_path=initial_path,
45 backend=backend,
46 title=title,
47 mode=browser_mode,
48 selection_mode=selection_mode,
49 filter_extensions=filter_extensions,
50 default_filename=default_filename,
51 cache_key=cache_key,
52 on_result_callback=on_result_callback,
53 caller_id=caller_id,
54 enable_multi_selection=enable_multi_selection,
55 )
57 async def open_config_window(
58 self,
59 config_class: Type,
60 current_config: Any,
61 on_save_callback: Optional[Callable] = None
62 ):
63 """
64 Open config window with separate config_class and current_config parameters.
66 Supports both GlobalPipelineConfig (global) and PipelineConfig (per-orchestrator).
67 """
68 try:
69 window = self.app.query_one(ConfigWindow)
70 window.open_state = True
71 except NoMatches:
72 window = ConfigWindow(
73 config_class=config_class,
74 current_config=current_config,
75 on_save_callback=on_save_callback
76 )
77 await self.app.mount(window)
78 window.open_state = True
79 return window
81 async def open_multi_orchestrator_config(
82 self,
83 orchestrators: List,
84 on_save_callback: Optional[Callable] = None
85 ):
86 """Open multi-orchestrator config window without circular imports."""
87 # Lazy import to avoid circular dependency
88 from openhcs.textual_tui.windows.multi_orchestrator_config_window import (
89 show_multi_orchestrator_config
90 )
92 return await show_multi_orchestrator_config(
93 app=self.app,
94 orchestrators=orchestrators,
95 on_save_callback=on_save_callback
96 )