Suite des retours Dom sur la GUI V6 (par-dessus 6a0a581).
Addendum Profils / Réglages :
- Nouveau sous-onglet Administration « 👤 Profils » : le profil actif devient
un objet lisible (nom, description, masque requis, template, listes locales
avec compteurs) — données réelles lues depuis profile_defaults.
- Fenêtre « Tableau des termes » (terms_table_window.py) : table scrollable
avec recherche/filtre, colonnes Type/Terme/Source ; reste lisible à 50+
termes. Ajouter/éditer/supprimer désactivés « (à venir) » (écriture par
profil non câblée).
- Réglages : « Profil métier » → « Profil d'anonymisation », « Sortie… » →
« Dossier de sortie… » (+ infobulle), hints moteurs (standard/optionnel/
plus lent), bouton « Voir le profil », « Ouvrir le tableau des termes ».
- Aide « ? » + infobulles (ui_kit.attach_tooltip) près des éléments ambigus.
- profile_view.py : logique pure (résumé profil + lignes du tableau),
testable sans display.
Addendum bêta : en-tête « aivanonym » + badge « bêta », titre fenêtre
« … — bêta ». Détail version conservé dans À propos.
tests/unit/test_gui_v6_profiles.py + ajouts shell. 237 tests unit OK
(228 → 237, 0 régression), self-test GUI V6 OK, navigation des 5 sous-onglets
+ thème OK. V5/moteur/app_aivanov/profile_defaults non touchés, 0 dépendance.
Aucun build/push sans GO Dom — validation visuelle Dom attendue.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
70 lines
2.3 KiB
Python
70 lines
2.3 KiB
Python
"""Vue lisible d'un profil d'anonymisation (logique pure, testable sans display).
|
|
|
|
Un profil de ``profile_defaults`` est un dict riche (label, description,
|
|
require_manual_mask, force_disable_vlm, preferred_manual_mask_template,
|
|
param_lists). Ce module en extrait un résumé affichable et les lignes du
|
|
« tableau des termes » pour les utilisateurs non informaticiens.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
from typing import Any, Optional
|
|
|
|
# Ordre + libellés lisibles des listes locales d'un profil.
|
|
LIST_LABELS = {
|
|
"whitelist_phrases": "À conserver",
|
|
"blacklist_force_mask_terms": "À masquer",
|
|
"additional_stopwords": "À ignorer",
|
|
}
|
|
|
|
|
|
@dataclass
|
|
class ProfileSummary:
|
|
key: str
|
|
label: str
|
|
description: str
|
|
require_manual_mask: bool
|
|
mask_template: str # "" si aucun
|
|
disable_vlm: bool
|
|
list_counts: dict[str, int]
|
|
|
|
|
|
def summarize_profile(key: str, profile: Optional[dict[str, Any]]) -> ProfileSummary:
|
|
profile = profile or {}
|
|
param_lists = profile.get("param_lists") or {}
|
|
counts = {
|
|
label: len(param_lists.get(raw) or [])
|
|
for raw, label in LIST_LABELS.items()
|
|
}
|
|
return ProfileSummary(
|
|
key=key,
|
|
label=str(profile.get("label") or key or "—"),
|
|
description=str(profile.get("description") or ""),
|
|
require_manual_mask=bool(profile.get("require_manual_mask")),
|
|
mask_template=str(profile.get("preferred_manual_mask_template") or ""),
|
|
disable_vlm=bool(profile.get("force_disable_vlm")),
|
|
list_counts=counts,
|
|
)
|
|
|
|
|
|
def profile_term_rows(profile: Optional[dict[str, Any]]) -> list[tuple[str, str, str]]:
|
|
"""Lignes ``(type, terme, source)`` pour le tableau des termes du profil."""
|
|
profile = profile or {}
|
|
source = str(profile.get("label") or "")
|
|
param_lists = profile.get("param_lists") or {}
|
|
rows: list[tuple[str, str, str]] = []
|
|
for raw, type_label in LIST_LABELS.items():
|
|
for term in (param_lists.get(raw) or []):
|
|
rows.append((type_label, str(term), source))
|
|
return rows
|
|
|
|
|
|
def filter_term_rows(
|
|
rows: list[tuple[str, str, str]], query: str
|
|
) -> list[tuple[str, str, str]]:
|
|
q = (query or "").strip().lower()
|
|
if not q:
|
|
return list(rows)
|
|
return [r for r in rows if q in r[1].lower() or q in r[0].lower()]
|