111 lines
3.5 KiB
Python
111 lines
3.5 KiB
Python
import os
|
|
import json
|
|
from typing import Dict, List
|
|
from flask import Blueprint, render_template, request
|
|
|
|
from modules.projects.project_handler import ProjectHandler
|
|
|
|
projects_bp = Blueprint('projects', __name__)
|
|
_handler = ProjectHandler()
|
|
|
|
def _project_root() -> str:
|
|
# 3 niveaux au dessus de modules/projects/ = racine projet
|
|
return os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|
|
|
def _clients_dir() -> str:
|
|
return os.path.join(_project_root(), 'Data', 'clients')
|
|
|
|
def _load_clients_index() -> Dict[str, str]:
|
|
"""
|
|
Retourne un dict {client_id: client_name lisible}
|
|
client_id = nom de fichier sans extension dans Data/clients
|
|
"""
|
|
idx: Dict[str, str] = {}
|
|
cdir = _clients_dir()
|
|
if not os.path.isdir(cdir):
|
|
return idx
|
|
for fname in os.listdir(cdir):
|
|
if not fname.endswith('.json'):
|
|
continue
|
|
client_id = os.path.splitext(fname)[0]
|
|
path = os.path.join(cdir, fname)
|
|
try:
|
|
with open(path, 'r', encoding='utf-8') as f:
|
|
data = json.load(f)
|
|
name = data.get('client_name') or client_id.replace('_', ' ').title()
|
|
idx[client_id] = name
|
|
except Exception:
|
|
idx[client_id] = client_id.replace('_', ' ').title()
|
|
return idx
|
|
|
|
def _list_all_projects() -> List:
|
|
"""
|
|
Parcourt Data/projects/<client_id> et retourne la liste des objets Project.
|
|
"""
|
|
base = _handler.base_dir
|
|
projects = []
|
|
if os.path.isdir(base):
|
|
for client_id in os.listdir(base):
|
|
client_path = os.path.join(base, client_id)
|
|
if os.path.isdir(client_path):
|
|
projects.extend(_handler.list_projects(client_id))
|
|
return projects
|
|
|
|
@projects_bp.route('/projects', methods=['GET'])
|
|
def projects_index():
|
|
clients_idx = _load_clients_index()
|
|
selected_client = request.args.get('client_id', '').strip()
|
|
query = request.args.get('q', '').strip().lower()
|
|
|
|
# Charger tous les projets
|
|
projects = _list_all_projects()
|
|
|
|
# Filtre par client
|
|
if selected_client:
|
|
projects = [p for p in projects if p.client_id == selected_client]
|
|
|
|
# Recherche plein texte basique
|
|
if query:
|
|
def match(p) -> bool:
|
|
hay = ' '.join([
|
|
p.name or '',
|
|
p.status or '',
|
|
p.description or ''
|
|
]).lower()
|
|
return query in hay
|
|
projects = [p for p in projects if match(p)]
|
|
|
|
# Tri par updated_at décroissante
|
|
projects.sort(key=lambda p: p.updated_at or '', reverse=True)
|
|
|
|
# Transformer pour la vue (nom client)
|
|
def client_name_for(pid: str) -> str:
|
|
return clients_idx.get(pid, pid.replace('_', ' ').title())
|
|
|
|
view_projects = []
|
|
for p in projects:
|
|
view_projects.append({
|
|
'id': p.id,
|
|
'client_id': p.client_id,
|
|
'client_name': client_name_for(p.client_id),
|
|
'name': p.name,
|
|
'status': p.status,
|
|
'start_date': p.start_date,
|
|
'end_date': p.end_date,
|
|
'budget': p.budget,
|
|
'updated_at': p.updated_at
|
|
})
|
|
|
|
# Liste triée des clients pour le sélecteur
|
|
clients_for_select = sorted(
|
|
[{'id': cid, 'name': cname} for cid, cname in clients_idx.items()],
|
|
key=lambda c: c['name'].lower()
|
|
)
|
|
|
|
return render_template(
|
|
'projects/all_projects.html',
|
|
projects=view_projects,
|
|
clients=clients_for_select,
|
|
selected_client=selected_client,
|
|
q=request.args.get('q', '').strip()
|
|
)
|