176 lines
7.2 KiB
Python
176 lines
7.2 KiB
Python
import streamlit as st
|
|
from streamlit_arborist import tree_view
|
|
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 build_arborist_tree(tree, parent_path=Path()):
|
|
nodes = []
|
|
|
|
for name, content in sorted(tree.items()):
|
|
full_path = parent_path / name
|
|
node_id = str(full_path.as_posix())
|
|
|
|
if isinstance(content, dict):
|
|
nodes.append({
|
|
"id": node_id,
|
|
"name": f"{name}",
|
|
"children": build_arborist_tree(content, full_path)
|
|
})
|
|
else:
|
|
suffix = Path(name).suffix
|
|
icon = SUFFIX_MAP.get(suffix, SUFFIX_MAP["default"])
|
|
|
|
nodes.append({
|
|
"id": node_id,
|
|
"name": f"{icon} {name}",
|
|
"key": f"key_{node_id}"
|
|
})
|
|
|
|
return nodes
|
|
|
|
def render_filetree_arborist(tree):
|
|
data = build_arborist_tree(tree)
|
|
|
|
selected = tree_view(
|
|
data=data,
|
|
icons={"open": "📂", "closed": "📁"},
|
|
height=200,
|
|
selection=None,
|
|
select_internal_nodes=True,
|
|
open_by_default=False
|
|
)
|
|
|
|
return selected
|
|
|
|
|
|
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:
|
|
with st.container(border=False):
|
|
if not tree:
|
|
st.info("Workspace is empty.")
|
|
else:
|
|
selected = render_filetree_arborist(tree)
|
|
|
|
if selected:
|
|
selected_path = selected.get("id")
|
|
|
|
if st.session_state.last_selected != selected_path:
|
|
st.session_state.last_selected = selected_path
|
|
abs_path = fm.base_path / selected_path
|
|
|
|
if abs_path.is_file():
|
|
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()
|
|
|
|
elif abs_path.is_dir():
|
|
st.session_state.selected_folder = str(abs_path)
|
|
selected_folder = st.session_state.selected_folder
|
|
with st.popover(
|
|
f"📁 {Path(selected_folder).name}",
|
|
use_container_width=True,
|
|
key=f"{selected_folder}_popover_options"):
|
|
action = st.radio(
|
|
"Action",
|
|
["New File", "New Folder"],
|
|
key=f"radio_folder_options",
|
|
label_visibility="collapsed")
|
|
|
|
new_name = st.text_input("Name", key=f"input_folder_options")
|
|
|
|
btn_cols = st.columns([1,1,1])
|
|
with btn_cols[0]:
|
|
if st.button("Create", key=f"btn_create_subfile_or_subfolder"):
|
|
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(selected_path, new_name)
|
|
else:
|
|
fm.create_file(selected_path, new_name)
|
|
st.success(f"{action} created!")
|
|
st.session_state.selected_folder = None
|
|
st.rerun()
|
|
|
|
with btn_cols[1]:
|
|
if st.button("Cancel", key=f"cancel_folder_options"):
|
|
st.session_state.selected_folder = None
|
|
st.rerun()
|
|
|
|
with btn_cols[2]:
|
|
if st.button("Delete Folder", key=f"delete_folder"):
|
|
try:
|
|
fm.delete_folder(selected_path)
|
|
st.success(f"Folder '{Path(selected_folder).name}' deleted successfully!")
|
|
st.session_state.selected_folder = None
|
|
st.rerun()
|
|
except Exception as e:
|
|
st.error(f"Error deleting folder: {e}")
|
|
|
|
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")
|
|
st.sidebar.checkbox("Code Editor", key="show_Editor")
|
|
st.sidebar.checkbox("Chat with AI Assistant", key="show_Chat")
|
|
|
|
return
|
|
|
|
if __name__ == "__main__":
|
|
render_sidebar()
|
|
|