From 57ba9eaf0b0c51c98724fe48e211a5255dbbe41d Mon Sep 17 00:00:00 2001 From: leart-ramushi <113895250+leart-ramushi@users.noreply.github.com> Date: Thu, 21 May 2026 21:59:57 +0200 Subject: [PATCH] Test --- src/backend/file_manager.py | 38 ++----------- src/main.py | 110 ++++++++++++++++++++++-------------- src/ui/navigation.py | 55 +++++++++++------- 3 files changed, 107 insertions(+), 96 deletions(-) diff --git a/src/backend/file_manager.py b/src/backend/file_manager.py index 8c9532e..011b975 100644 --- a/src/backend/file_manager.py +++ b/src/backend/file_manager.py @@ -1,49 +1,23 @@ -import os from pathlib import Path class FileManager: """ - Verwaltet das Laden, Speichern und Auflisten von Code-Dateien inklusive Ordnerstruktur [1] + Handles file reading and writing """ + def __init__(self, root_path="."): self.root_path = Path(root_path).resolve() - def list_files(self, current_path=None): - """ - Gibt eine verschachtelte Struktur zurück, um Ordner und Dateien darzustellen [1] - """ - if current_path is None: - current_path = self.root_path - elif not isinstance(current_path, Path): - current_path = Path(current_path) - - items = [] - try: - for item in current_path.iterdir(): - if item.is_dir(): - items.append({"type": "folder", "name": item.name, "path": str(item)}) - elif item.is_file() and item.suffix in {'.py', '.js', '.html', '.css', '.md'}: - items.append({"type": "file", "name": item.name, "path": str(item)}) - except PermissionError: - pass - return items - def read_file(self, file_path): - """ - Liest und gibt den Inhalt einer Datei zurück [1] - """ try: - with open(file_path, 'r', encoding='utf-8') as f: + with open(file_path, "r", encoding="utf-8") as f: return f.read() - except Exception as e: - return None + except Exception: + return "" def save_file(self, file_path, content): - """ - Schreibt Inhalt in eine Datei [1] - """ try: - with open(file_path, 'w', encoding='utf-8') as f: + with open(file_path, "w", encoding="utf-8") as f: f.write(content) return True except Exception: diff --git a/src/main.py b/src/main.py index ef431ac..96205d2 100644 --- a/src/main.py +++ b/src/main.py @@ -1,21 +1,45 @@ import sys import os -project_root = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) +from pathlib import Path + +import streamlit as st +from streamlit_tree_select import tree_select + +# project path fix +project_root = os.path.abspath(os.path.dirname(__file__)) if project_root not in sys.path: sys.path.insert(0, project_root) -import streamlit as st +# backend +from backend.file_manager import FileManager +from ui.navigation import FileNavigation -# Backend-Imports -from src.backend.file_manager import FileManager -from src.backend.chat_manager import ChatManager -from src.backend.execution_engine import ExecutionEngine +# your existing modules (keep yours as-is) +from backend.chat_manager import ChatManager +from backend.execution_engine import ExecutionEngine +from ui.editor import CodeEditor +from ui.chat import ChatInterface +from ui.output import OutputDisplay + + +def render_sidebar(): + st.sidebar.title("📁 File Explorer") + + navigation = FileNavigation() + tree_data = navigation.build_tree() + + with st.sidebar: + selection = tree_select( + tree_data, + check_model="leaf", + only_leaf_checkboxes=True + ) + + if selection and selection.get("checked"): + return selection["checked"][0] + + return None -# UI-Imports -from src.ui.navigation import FileNavigation -from src.ui.editor import CodeEditor -from src.ui.chat import ChatInterface -from src.ui.output import OutputDisplay def main(): st.set_page_config( @@ -24,49 +48,49 @@ def main(): layout="wide" ) - # Initialisiere Manager-Klassen file_manager = FileManager() chat_manager = ChatManager() execution_engine = ExecutionEngine() - if "selected_file" not in st.session_state: st.session_state.selected_file = None - if "file_history" not in st.session_state: - st.session_state.file_history = [] - # Sidebar für Dateinavigation - st.sidebar.title("📁 Datei-Explorer") - st.sidebar.subheader("Wähle eine Datei aus") + # --- SIDEBAR --- + selected_file = render_sidebar() - navigation = FileNavigation() - file_list = navigation.list_files() - - if file_list: - selected_file = st.sidebar.selectbox("Dateien", file_list) - if selected_file: - content = file_manager.read_file(selected_file) - st.session_state.selected_file = selected_file - - col1, col2 = st.columns([3, 2]) - - with col1: - editor = CodeEditor() - editor.display_code(content) - - if st.button("💾 Speichern"): - file_manager.save_file(selected_file, content) - st.success("Datei gespeichert!") - - with col2: - chat = ChatInterface() - chat.display_chat(chat_manager) - - output = OutputDisplay() - output.display_execution(execution_engine) + if selected_file: + st.session_state.selected_file = selected_file st.sidebar.markdown("---") st.sidebar.caption("AISE501 – AI in Software Engineering") + # --- MAIN AREA --- + if st.session_state.selected_file: + + content = file_manager.read_file(st.session_state.selected_file) + + col1, col2 = st.columns([3, 2]) + + with col1: + st.subheader(f"Editing: {Path(st.session_state.selected_file).name}") + + editor = CodeEditor() + editor.display_code(content) + + if st.button("💾 Save"): + file_manager.save_file(st.session_state.selected_file, content) + st.success("File saved!") + + with col2: + chat = ChatInterface() + chat.display_chat(chat_manager) + + output = OutputDisplay() + output.display_execution(execution_engine) + + else: + st.info("Select a file from the sidebar explorer 👈") + + if __name__ == "__main__": main() \ No newline at end of file diff --git a/src/ui/navigation.py b/src/ui/navigation.py index 81d4bd8..985c9ba 100644 --- a/src/ui/navigation.py +++ b/src/ui/navigation.py @@ -1,30 +1,43 @@ -import os from pathlib import Path class FileNavigation: """ - Navigation für die Dateiauswahl in der Sidebar [1] + Builds a VS Code-like file tree for streamlit_tree_select """ - + def __init__(self): self.supported_extensions = {'.py', '.js', '.html', '.css', '.json', '.md'} - - def list_files(self, path=None): - """ - Listet alle Code-Dateien im aktuellen Verzeichnis auf [1] - """ + + def build_tree(self, path=None): if path is None: path = Path.cwd() - - file_list = [] - for root, dirs, files in os.walk(path): - for file in files: - if os.path.splitext(file)[1] in self.supported_extensions: - file_list.append(file) - return sorted(file_list) - - def get_full_path(self, filename): - """ - Gibt den vollständigen Pfad der Datei zurück - """ - return Path(filename) \ No newline at end of file + + path = Path(path) + + def build_node(current_path: Path): + is_dir = current_path.is_dir() + + node = { + "label": ("📁 " if is_dir else "📄 ") + current_path.name, + "value": str(current_path), + } + + if is_dir: + children = [] + + try: + for item in sorted( + current_path.iterdir(), + key=lambda x: (not x.is_dir(), x.name.lower()) + ): + if item.is_dir() or item.suffix in self.supported_extensions: + children.append(build_node(item)) + except PermissionError: + pass + + node["children"] = children + + return node + + # IMPORTANT: must return a LIST + return [build_node(path)] \ No newline at end of file