Merge branch 'main' into onboarding-completion-trigger

This commit is contained in:
Mike Fortman 2025-11-21 16:31:36 -06:00 committed by GitHub
commit b1bad91f02
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 113 additions and 63 deletions

View file

@ -366,6 +366,21 @@ class OpenRAGTUI(App):
self.env_manager = EnvManager() self.env_manager = EnvManager()
self.docling_manager = DoclingManager() # Initialize singleton instance self.docling_manager = DoclingManager() # Initialize singleton instance
def notify(
self,
message: str,
*,
title: str = "",
severity: str = "information",
timeout: float | None = None,
markup: bool = True,
) -> None:
"""Override notify to make notifications last 20 seconds by default."""
# If timeout is None (default), make it 20 seconds
if timeout is None:
timeout = 20.0
super().notify(message, title=title, severity=severity, timeout=timeout, markup=markup)
def on_mount(self) -> None: def on_mount(self) -> None:
"""Initialize the application.""" """Initialize the application."""
# Check for runtime availability and show appropriate screen # Check for runtime availability and show appropriate screen

View file

@ -116,21 +116,8 @@ class EnvManager:
return f"'{escaped_value}'" return f"'{escaped_value}'"
def load_existing_env(self) -> bool: def load_existing_env(self) -> bool:
"""Load existing .env file if it exists.""" """Load existing .env file if it exists, or fall back to environment variables."""
if not self.env_file.exists(): import os
return False
try:
with open(self.env_file, "r") as f:
for line in f:
line = line.strip()
if not line or line.startswith("#"):
continue
if "=" in line:
key, value = line.split("=", 1)
key = key.strip()
value = sanitize_env_value(value)
# Map env vars to config attributes # Map env vars to config attributes
attr_map = { attr_map = {
@ -164,14 +151,40 @@ class EnvManager:
"DISABLE_INGEST_WITH_LANGFLOW": "disable_ingest_with_langflow", "DISABLE_INGEST_WITH_LANGFLOW": "disable_ingest_with_langflow",
} }
loaded_from_file = False
# Try to load from .env file first
if self.env_file.exists():
try:
with open(self.env_file, "r") as f:
for line in f:
line = line.strip()
if not line or line.startswith("#"):
continue
if "=" in line:
key, value = line.split("=", 1)
key = key.strip()
value = sanitize_env_value(value)
if key in attr_map: if key in attr_map:
setattr(self.config, attr_map[key], value) setattr(self.config, attr_map[key], value)
return True loaded_from_file = True
except Exception as e: except Exception as e:
logger.error("Error loading .env file", error=str(e)) logger.error("Error loading .env file", error=str(e))
return False
# Fall back to environment variables if .env file doesn't exist or failed to load
if not loaded_from_file:
logger.info("No .env file found, loading from environment variables")
for env_key, attr_name in attr_map.items():
value = os.environ.get(env_key, "")
if value:
setattr(self.config, attr_name, value)
return True
return loaded_from_file
def setup_secure_defaults(self) -> None: def setup_secure_defaults(self) -> None:
"""Set up secure default values for passwords and keys.""" """Set up secure default values for passwords and keys."""

View file

@ -146,6 +146,9 @@ class ConfigScreen(Screen):
self.env_manager = EnvManager() self.env_manager = EnvManager()
self.inputs = {} self.inputs = {}
# Check if .env file exists
self.has_env_file = self.env_manager.env_file.exists()
# Load existing config if available # Load existing config if available
self.env_manager.load_existing_env() self.env_manager.load_existing_env()
@ -156,12 +159,15 @@ class ConfigScreen(Screen):
with ScrollableContainer(id="config-scroll"): with ScrollableContainer(id="config-scroll"):
with Vertical(id="config-form"): with Vertical(id="config-form"):
yield from self._create_all_fields() yield from self._create_all_fields()
yield Horizontal( # Create button row - conditionally include Back button
buttons = [
Button("Generate Passwords", variant="default", id="generate-btn"), Button("Generate Passwords", variant="default", id="generate-btn"),
Button("Save Configuration", variant="success", id="save-btn"), Button("Save Configuration", variant="success", id="save-btn"),
Button("Back", variant="default", id="back-btn"), ]
classes="button-row", # Only show Back button if .env file exists
) if self.has_env_file:
buttons.append(Button("Back", variant="default", id="back-btn"))
yield Horizontal(*buttons, classes="button-row")
yield Footer() yield Footer()
def _create_header_text(self) -> Text: def _create_header_text(self) -> Text:

View file

@ -22,13 +22,6 @@ class WelcomeScreen(Screen):
BINDINGS = [ BINDINGS = [
("q", "quit", "Quit"), ("q", "quit", "Quit"),
("enter", "default_action", "Continue"),
("1", "no_auth_setup", "Basic Setup"),
("2", "full_setup", "Advanced Setup"),
("3", "monitor", "Status"),
("4", "diagnostics", "Diagnostics"),
("5", "start_stop_services", "Start/Stop Services"),
("6", "open_app", "Open App"),
] ]
def __init__(self): def __init__(self):
@ -42,6 +35,9 @@ class WelcomeScreen(Screen):
self.default_button_id = "basic-setup-btn" self.default_button_id = "basic-setup-btn"
self._state_checked = False self._state_checked = False
# Check if .env file exists
self.has_env_file = self.env_manager.env_file.exists()
# Load .env file if it exists # Load .env file if it exists
load_dotenv() load_dotenv()
@ -161,6 +157,23 @@ class WelcomeScreen(Screen):
buttons = [] buttons = []
# If no .env file exists, only show setup buttons
if not self.has_env_file:
if has_oauth:
# If OAuth is configured, only show advanced setup
buttons.append(
Button("Advanced Setup", variant="success", id="advanced-setup-btn")
)
else:
# If no OAuth, show both options with basic as primary
buttons.append(
Button("Basic Setup", variant="success", id="basic-setup-btn")
)
buttons.append(
Button("Advanced Setup", variant="default", id="advanced-setup-btn")
)
return Horizontal(*buttons, classes="button-row")
# Check if all services (native + container) are running # Check if all services (native + container) are running
all_services_running = self.services_running and self.docling_running all_services_running = self.services_running and self.docling_running
@ -189,7 +202,7 @@ class WelcomeScreen(Screen):
) )
buttons.append( buttons.append(
Button("Start All Services", variant="primary", id="start-all-services-btn") Button("Start OpenRAG", variant="primary", id="start-all-services-btn")
) )
# Always show status option # Always show status option
@ -253,6 +266,9 @@ class WelcomeScreen(Screen):
async def on_screen_resume(self) -> None: async def on_screen_resume(self) -> None:
"""Called when returning from another screen (e.g., config screen).""" """Called when returning from another screen (e.g., config screen)."""
# Check if .env file exists (may have been created)
self.has_env_file = self.env_manager.env_file.exists()
# Reload environment variables # Reload environment variables
load_dotenv(override=True) load_dotenv(override=True)