2026-04-06 21:14:27 +02:00

173 lines
7.4 KiB
Python

import streamlit as st
from pathlib import Path
from backend.managers.file_manager import FileManager
fm = FileManager()
SUFFIX_MAP = {
".py": "🐍", # Python
".js": "🟨", # JavaScript (Gelbes Quadrat/Logo)
".html": "🌐", # HTML (Web)
".css": "🎨", # CSS (Styling)
".json": "📦", # JSON (Datenpaket)
".yaml": "⚙️", # YAML (Konfiguration)
".yml": "⚙️", # YAML
".sh": "🐚", # Bash/Shell (Shell-Icon)
".md": "📝", # Markdown
".txt": "📄", # Text
".tex": "📑", # LaTeX
".c": "🔵", # C (Blaues Icon)
".cpp": "🔷", # C++
".java": "", # Java
"folder": "📁", # Ordner
"default": "📄" # Unbekannt
}
def render_filetree(tree, parent_path=Path()):
for name, content in sorted(tree.items()):
full_path = parent_path / name
if isinstance(content, dict): # Directory
disp_name = name if len(name) <= 13 else (name[:10] + "...")
with st.expander(f"📁 {disp_name}", expanded=False):
render_filetree(content, full_path)
with st.popover("+", key=f"popover_{full_path}"):
st.write(f"**Create in {name}**")
action = st.radio("Action", ["New File", "New Folder"], key=f"radio_{full_path}", label_visibility="collapsed")
new_name = st.text_input("Name", key=f"input_{full_path}")
if st.button("Create", key=f"btn_{full_path}"):
if "/" in new_name or "\\" in new_name:
st.warning("Do not include slashes in names!")
elif new_name and action == "New Folder":
fm.create_folder(str(full_path), new_name)
st.success(f"Folder {new_name} created!")
st.rerun()
elif new_name and action == "New File":
fm.create_file(str(full_path), new_name)
st.success(f"File {new_name} created!")
st.rerun()
else: # File
suffix = Path(name).suffix
icon = SUFFIX_MAP.get(suffix, SUFFIX_MAP["default"])
disp_name = name if len(name) <= 13 else (name[:10] + "...")
col_file, col_opt = st.columns([0.85, 0.15], gap="small")
with col_file:
if st.button(f"{icon} {disp_name}", key=str(full_path)):
abs_path = fm.base_path / full_path
if str(abs_path) not in st.session_state.open_files:
st.session_state.open_files.append(str(abs_path))
st.session_state.active_file = str(abs_path)
st.rerun()
with col_opt:
with st.popover("", key=f"opt_{full_path}"):
delete_key = f"confirm_delete_{full_path}"
if delete_key not in st.session_state:
st.session_state[delete_key] = False
if st.button(" **Delete** 🗑️", key=f"del_{full_path}"):
st.session_state[delete_key] = True
if st.session_state[delete_key]:
st.warning(f"Delete {name}?")
confirm_col, deny_col = st.columns([1, 1], gap="small")
with confirm_col:
if st.button("", key=f"yes_{full_path}"):
try:
fm.delete_file(str(full_path))
st.session_state[delete_key] = False
st.rerun()
except Exception as e:
st.error(f"Error deleting file: {e}")
with deny_col:
if st.button("", key=f"cancel_{full_path}"):
st.session_state[delete_key] = False
rename_key = f"rename_mode_{full_path}"
if rename_key not in st.session_state:
st.session_state[rename_key] = False
if st.button("**Rename** ✏️", key=f"ren_{full_path}"):
st.session_state[rename_key] = True
if st.session_state[rename_key]:
new_name = st.text_input("New Name", key=f"input_ren_{full_path}")
apply_col, cancel_col = st.columns([1, 1], gap="small")
with apply_col:
if st.button("Apply", key=f"apply_ren_{full_path}"):
try:
fm.rename_file(str(full_path), new_name)
st.session_state[rename_key] = False
st.rerun()
except Exception as e:
st.error(f"Error renaming file: {e}")
with cancel_col:
if st.button("Cancel", key=f"cancel_ren_{full_path}"):
st.session_state[rename_key] = False
def render_sidebar():
st.sidebar.title("Navigation")
file_explorer_section = st.sidebar.container()
navigation_section = st.sidebar.container()
with file_explorer_section:
st.subheader("File Explorer")
tree = fm.get_file_tree()
workspace = st.container()
add_more = st.container()
with workspace:
if not tree:
st.info("Workspace is empty.")
else:
render_filetree(tree)
with add_more:
with st.popover("⚙️ Explorer_Options", key=f"popover_options"):
action = st.radio(
"Action",
["New File", "New Folder"],
key=f"radio_explorer_options",
label_visibility="collapsed")
new_name = st.text_input("Name", key=f"input_explorer_options")
if st.button("Create", key=f"btn_create_file_or_folder"):
if "/" in new_name or "\\" in new_name:
st.warning("Do not include slashes in names!")
elif new_name:
if action == "New Folder":
fm.create_folder("", new_name)
else:
fm.create_file("", new_name)
st.success(f"{action} created!")
st.rerun()
st.sidebar.markdown("---")
with navigation_section:
st.sidebar.subheader("Options")
options = ["Code Editor", "Chat with AI Assistant"]
choice = []
for option in options:
if st.sidebar.checkbox(option):
choice.append(option)
return choice
if __name__ == "__main__":
render_sidebar()