tui warning
This commit is contained in:
parent
333498b073
commit
7768d4cef7
4 changed files with 166 additions and 1 deletions
|
|
@ -19,6 +19,7 @@ from ..managers.container_manager import ContainerManager, ServiceStatus, Servic
|
||||||
from ..managers.docling_manager import DoclingManager
|
from ..managers.docling_manager import DoclingManager
|
||||||
from ..utils.platform import RuntimeType
|
from ..utils.platform import RuntimeType
|
||||||
from ..widgets.command_modal import CommandOutputModal
|
from ..widgets.command_modal import CommandOutputModal
|
||||||
|
from ..widgets.flow_backup_warning_modal import FlowBackupWarningModal
|
||||||
from ..widgets.diagnostics_notification import notify_with_diagnostics
|
from ..widgets.diagnostics_notification import notify_with_diagnostics
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -356,6 +357,16 @@ class MonitorScreen(Screen):
|
||||||
"""Upgrade services with progress updates."""
|
"""Upgrade services with progress updates."""
|
||||||
self.operation_in_progress = True
|
self.operation_in_progress = True
|
||||||
try:
|
try:
|
||||||
|
# Check for flow backups before upgrading
|
||||||
|
if self._check_flow_backups():
|
||||||
|
# Show warning modal and wait for user decision
|
||||||
|
should_continue = await self.app.push_screen_wait(
|
||||||
|
FlowBackupWarningModal(operation="upgrade")
|
||||||
|
)
|
||||||
|
if not should_continue:
|
||||||
|
self.notify("Upgrade cancelled", severity="information")
|
||||||
|
return
|
||||||
|
|
||||||
# Show command output in modal dialog
|
# Show command output in modal dialog
|
||||||
command_generator = self.container_manager.upgrade_services()
|
command_generator = self.container_manager.upgrade_services()
|
||||||
modal = CommandOutputModal(
|
modal = CommandOutputModal(
|
||||||
|
|
@ -371,6 +382,16 @@ class MonitorScreen(Screen):
|
||||||
"""Reset services with progress updates."""
|
"""Reset services with progress updates."""
|
||||||
self.operation_in_progress = True
|
self.operation_in_progress = True
|
||||||
try:
|
try:
|
||||||
|
# Check for flow backups before resetting
|
||||||
|
if self._check_flow_backups():
|
||||||
|
# Show warning modal and wait for user decision
|
||||||
|
should_continue = await self.app.push_screen_wait(
|
||||||
|
FlowBackupWarningModal(operation="reset")
|
||||||
|
)
|
||||||
|
if not should_continue:
|
||||||
|
self.notify("Reset cancelled", severity="information")
|
||||||
|
return
|
||||||
|
|
||||||
# Show command output in modal dialog
|
# Show command output in modal dialog
|
||||||
command_generator = self.container_manager.reset_services()
|
command_generator = self.container_manager.reset_services()
|
||||||
modal = CommandOutputModal(
|
modal = CommandOutputModal(
|
||||||
|
|
@ -382,6 +403,20 @@ class MonitorScreen(Screen):
|
||||||
finally:
|
finally:
|
||||||
self.operation_in_progress = False
|
self.operation_in_progress = False
|
||||||
|
|
||||||
|
def _check_flow_backups(self) -> bool:
|
||||||
|
"""Check if there are any flow backups in ./flows/backup directory."""
|
||||||
|
from pathlib import Path
|
||||||
|
backup_dir = Path("flows/backup")
|
||||||
|
if not backup_dir.exists():
|
||||||
|
return False
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Check if there are any .json files in the backup directory
|
||||||
|
backup_files = list(backup_dir.glob("*.json"))
|
||||||
|
return len(backup_files) > 0
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
|
||||||
async def _start_docling_serve(self) -> None:
|
async def _start_docling_serve(self) -> None:
|
||||||
"""Start docling serve."""
|
"""Start docling serve."""
|
||||||
self.operation_in_progress = True
|
self.operation_in_progress = True
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ class WelcomeScreen(Screen):
|
||||||
self.has_oauth_config = False
|
self.has_oauth_config = False
|
||||||
self.default_button_id = "basic-setup-btn"
|
self.default_button_id = "basic-setup-btn"
|
||||||
self._state_checked = False
|
self._state_checked = False
|
||||||
|
self.has_flow_backups = False
|
||||||
|
|
||||||
# Check if .env file exists
|
# Check if .env file exists
|
||||||
self.has_env_file = self.env_manager.env_file.exists()
|
self.has_env_file = self.env_manager.env_file.exists()
|
||||||
|
|
@ -45,6 +46,9 @@ class WelcomeScreen(Screen):
|
||||||
self.has_oauth_config = bool(os.getenv("GOOGLE_OAUTH_CLIENT_ID")) or bool(
|
self.has_oauth_config = bool(os.getenv("GOOGLE_OAUTH_CLIENT_ID")) or bool(
|
||||||
os.getenv("MICROSOFT_GRAPH_OAUTH_CLIENT_ID")
|
os.getenv("MICROSOFT_GRAPH_OAUTH_CLIENT_ID")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Check for flow backups
|
||||||
|
self.has_flow_backups = self._check_flow_backups()
|
||||||
|
|
||||||
def compose(self) -> ComposeResult:
|
def compose(self) -> ComposeResult:
|
||||||
"""Create the welcome screen layout."""
|
"""Create the welcome screen layout."""
|
||||||
|
|
@ -61,6 +65,19 @@ class WelcomeScreen(Screen):
|
||||||
)
|
)
|
||||||
yield Footer()
|
yield Footer()
|
||||||
|
|
||||||
|
def _check_flow_backups(self) -> bool:
|
||||||
|
"""Check if there are any flow backups in ./flows/backup directory."""
|
||||||
|
backup_dir = Path("flows/backup")
|
||||||
|
if not backup_dir.exists():
|
||||||
|
return False
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Check if there are any .json files in the backup directory
|
||||||
|
backup_files = list(backup_dir.glob("*.json"))
|
||||||
|
return len(backup_files) > 0
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
|
||||||
def _detect_services_sync(self) -> None:
|
def _detect_services_sync(self) -> None:
|
||||||
"""Synchronously detect if services are running."""
|
"""Synchronously detect if services are running."""
|
||||||
if not self.container_manager.is_available():
|
if not self.container_manager.is_available():
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
"""Widgets for OpenRAG TUI."""
|
"""Widgets for OpenRAG TUI."""
|
||||||
|
|
||||||
# Made with Bob
|
from .flow_backup_warning_modal import FlowBackupWarningModal
|
||||||
|
|
||||||
|
__all__ = ["FlowBackupWarningModal"]
|
||||||
|
|
||||||
|
# Made with Bob
|
||||||
109
src/tui/widgets/flow_backup_warning_modal.py
Normal file
109
src/tui/widgets/flow_backup_warning_modal.py
Normal file
|
|
@ -0,0 +1,109 @@
|
||||||
|
"""Flow backup warning modal for OpenRAG TUI."""
|
||||||
|
|
||||||
|
from textual.app import ComposeResult
|
||||||
|
from textual.containers import Container, Horizontal
|
||||||
|
from textual.screen import ModalScreen
|
||||||
|
from textual.widgets import Button, Static, Label
|
||||||
|
|
||||||
|
|
||||||
|
class FlowBackupWarningModal(ModalScreen[bool]):
|
||||||
|
"""Modal dialog to warn about flow backups before upgrade/reset."""
|
||||||
|
|
||||||
|
DEFAULT_CSS = """
|
||||||
|
FlowBackupWarningModal {
|
||||||
|
align: center middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
#dialog {
|
||||||
|
width: 70;
|
||||||
|
height: auto;
|
||||||
|
border: solid #3f3f46;
|
||||||
|
background: #27272a;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#title {
|
||||||
|
background: #3f3f46;
|
||||||
|
color: #fafafa;
|
||||||
|
padding: 1 2;
|
||||||
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
text-style: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
#message {
|
||||||
|
padding: 2;
|
||||||
|
color: #fafafa;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#button-row {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
align: center middle;
|
||||||
|
padding: 1;
|
||||||
|
margin-top: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#button-row Button {
|
||||||
|
margin: 0 1;
|
||||||
|
min-width: 16;
|
||||||
|
background: #27272a;
|
||||||
|
color: #fafafa;
|
||||||
|
border: round #52525b;
|
||||||
|
text-style: none;
|
||||||
|
tint: transparent 0%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#button-row Button:hover {
|
||||||
|
background: #27272a !important;
|
||||||
|
color: #fafafa !important;
|
||||||
|
border: round #52525b;
|
||||||
|
tint: transparent 0%;
|
||||||
|
text-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#button-row Button:focus {
|
||||||
|
background: #27272a !important;
|
||||||
|
color: #fafafa !important;
|
||||||
|
border: round #ec4899;
|
||||||
|
tint: transparent 0%;
|
||||||
|
text-style: none;
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, operation: str = "upgrade"):
|
||||||
|
"""Initialize the warning modal.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
operation: The operation being performed ("upgrade" or "reset")
|
||||||
|
"""
|
||||||
|
super().__init__()
|
||||||
|
self.operation = operation
|
||||||
|
|
||||||
|
def compose(self) -> ComposeResult:
|
||||||
|
"""Create the modal dialog layout."""
|
||||||
|
with Container(id="dialog"):
|
||||||
|
yield Label("⚠ Flow Backups Detected", id="title")
|
||||||
|
yield Static(
|
||||||
|
f"Flow backups found in ./flows/backup\n\n"
|
||||||
|
f"Proceeding with {self.operation} will reset custom flows to defaults.\n"
|
||||||
|
f"Your customizations are backed up and will need to be\n"
|
||||||
|
f"manually imported and upgraded to work with the latest version.\n\n"
|
||||||
|
f"Do you want to continue?",
|
||||||
|
id="message"
|
||||||
|
)
|
||||||
|
with Horizontal(id="button-row"):
|
||||||
|
yield Button("Cancel", id="cancel-btn")
|
||||||
|
yield Button(f"Continue {self.operation.title()}", id="continue-btn")
|
||||||
|
|
||||||
|
def on_mount(self) -> None:
|
||||||
|
"""Focus the cancel button by default for safety."""
|
||||||
|
self.query_one("#cancel-btn", Button).focus()
|
||||||
|
|
||||||
|
def on_button_pressed(self, event: Button.Pressed) -> None:
|
||||||
|
"""Handle button presses."""
|
||||||
|
if event.button.id == "continue-btn":
|
||||||
|
self.dismiss(True) # User wants to continue
|
||||||
|
else:
|
||||||
|
self.dismiss(False) # User cancelled
|
||||||
Loading…
Add table
Reference in a new issue