180 lines
7.3 KiB
Python
180 lines
7.3 KiB
Python
import flet as ft
|
|
import requests
|
|
|
|
class StandardDocuments:
|
|
def __init__(self, page: ft.Page, home):
|
|
self.page = page
|
|
self.home = home
|
|
self.base_url = self.page.session.store.get('api_base_url')
|
|
self.token = self.page.session.store.get('token')
|
|
|
|
self.all_documents = [] # Stocăm documentele pentru filtrare locală (căutare după nume)
|
|
|
|
# Elemente UI
|
|
self.search_bar = ft.TextField(
|
|
label="Caută document după nume",
|
|
on_change=self._on_search_change,
|
|
expand=True,
|
|
prefix_icon=ft.Icons.SEARCH,
|
|
hint_text="Introdu numele documentului..."
|
|
)
|
|
|
|
self.category_dropdown = ft.Dropdown(
|
|
label="Filtrează după categorie",
|
|
on_select=self._on_category_change,
|
|
width=300,
|
|
hint_text="Alege o categorie"
|
|
)
|
|
|
|
self.documents_list_view = ft.ListView(
|
|
expand=True,
|
|
spacing=10,
|
|
padding=10
|
|
)
|
|
|
|
def _on_search_change(self, e):
|
|
"""Filtrează lista de documente afișată în funcție de textul din search bar."""
|
|
query = self.search_bar.value.lower().strip()
|
|
filtered = [
|
|
doc for doc in self.all_documents
|
|
if query in doc['name'].lower()
|
|
]
|
|
self._populate_documents_list(filtered)
|
|
|
|
def _on_category_change(self, e):
|
|
"""Reîncarcă documentele atunci când se schimbă categoria selectată."""
|
|
self._load_documents(self.category_dropdown.value)
|
|
|
|
def _load_categories(self):
|
|
"""Preia categoriile de documente de la server."""
|
|
try:
|
|
response = requests.get(
|
|
f"{self.base_url}/documents/categories",
|
|
headers={"Authorization": f"Bearer {self.token}"}
|
|
)
|
|
if response.status_code == 200:
|
|
user_data = self.page.session.store.get('user')
|
|
user_role = user_data.get('role', '').lower() if user_data else ""
|
|
|
|
all_cats = response.json()
|
|
# Filtrare categorii după rol: utilizatorul vede categoria doar dacă
|
|
# rolul său se regăsește în câmpul 'access' (comma-separated string)
|
|
filtered_cats = [
|
|
cat for cat in all_cats
|
|
if user_role in [r.strip().lower() for r in cat.get('access', '').split(',')]
|
|
]
|
|
|
|
self.category_dropdown.options = [
|
|
ft.dropdown.Option(key="all", text="Toate categoriile")
|
|
] + [
|
|
ft.dropdown.Option(key=str(cat['id']), text=cat['name'])
|
|
for cat in filtered_cats
|
|
]
|
|
self.category_dropdown.value = "all"
|
|
self.page.update()
|
|
except Exception as ex:
|
|
print(f"Error fetching categories: {ex}")
|
|
|
|
def _load_documents(self, category_id="all"):
|
|
"""Preia documentele standard de la server."""
|
|
try:
|
|
if category_id == "all":
|
|
url = f"{self.base_url}/documents/standards"
|
|
else:
|
|
url = f"{self.base_url}/documents/standards/category/{category_id}"
|
|
|
|
response = requests.get(
|
|
url,
|
|
headers={"Authorization": f"Bearer {self.token}"}
|
|
)
|
|
if response.status_code == 200:
|
|
user_data = self.page.session.store.get('user')
|
|
user_role = user_data.get('role', '').lower() if user_data else ""
|
|
|
|
raw_docs = response.json()
|
|
# Filtrare documente după rol: utilizatorul vede documentul doar dacă
|
|
# rolul său se regăsește în câmpul 'access' (comma-separated string)
|
|
self.all_documents = [
|
|
doc for doc in raw_docs
|
|
if user_role in [r.strip().lower() for r in doc.get('access', '').split(',')]
|
|
]
|
|
|
|
# Aplicăm și filtrul de căutare dacă există deja text în search bar
|
|
query = self.search_bar.value.lower().strip()
|
|
filtered = [d for d in self.all_documents if query in d['name'].lower()]
|
|
self._populate_documents_list(filtered)
|
|
except Exception as ex:
|
|
print(f"Error fetching documents: {ex}")
|
|
|
|
def _populate_documents_list(self, documents):
|
|
"""Actualizează interfața cu lista de documente furnizată."""
|
|
self.documents_list_view.controls = []
|
|
if not documents:
|
|
self.documents_list_view.controls.append(
|
|
ft.Container(
|
|
content=ft.Text("Nu s-au găsit documente.", size=16, color=ft.Colors.GREY_600),
|
|
alignment=ft.Alignment.CENTER,
|
|
padding=20
|
|
)
|
|
)
|
|
else:
|
|
for doc in documents:
|
|
self.documents_list_view.controls.append(
|
|
ft.Container(
|
|
content=ft.Row(
|
|
[
|
|
ft.Icon(ft.Icons.INSERT_DRIVE_FILE_OUTLINED, color=ft.Colors.BLUE_700),
|
|
ft.Column(
|
|
[
|
|
ft.Text(doc['name'], weight=ft.FontWeight.BOLD, size=16),
|
|
ft.Text(f"Path: {doc['path']}", size=12, color=ft.Colors.GREY_500),
|
|
],
|
|
expand=True,
|
|
alignment=ft.MainAxisAlignment.CENTER
|
|
),
|
|
ft.IconButton(
|
|
icon=ft.Icons.DOWNLOAD,
|
|
tooltip="Descarcă documentul",
|
|
icon_color=ft.Colors.BLUE_700,
|
|
on_click=lambda e, d=doc: self.page.run_task(self._download_document, d)
|
|
)
|
|
],
|
|
alignment=ft.MainAxisAlignment.SPACE_BETWEEN
|
|
),
|
|
bgcolor=ft.Colors.BLUE_50,
|
|
padding=15,
|
|
border_radius=10,
|
|
border=ft.Border.all(1, ft.Colors.BLUE_100),
|
|
ink=True
|
|
)
|
|
)
|
|
self.page.update()
|
|
|
|
async def _download_document(self, doc):
|
|
"""Deschide URL-ul de download pentru documentul selectat."""
|
|
download_url = f"{self.base_url}/documents/download?path={doc['path']}&token={self.token}"
|
|
await self.page.launch_url(download_url)
|
|
|
|
def build(self):
|
|
# Încărcare inițială a datelor
|
|
self._load_categories()
|
|
self._load_documents()
|
|
|
|
return ft.Container(
|
|
content=ft.Column(
|
|
[
|
|
ft.Row(
|
|
[
|
|
self.category_dropdown,
|
|
self.search_bar
|
|
],
|
|
spacing=20
|
|
),
|
|
ft.Divider(height=1, color=ft.Colors.GREY_300),
|
|
self.documents_list_view
|
|
],
|
|
expand=True
|
|
),
|
|
expand=True,
|
|
padding=20
|
|
) |