feat(gui): addenda Dom GUI V6 — sous-onglet Profils, libellés, aide, bêta
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>
This commit is contained in:
69
gui_v6/profile_view.py
Normal file
69
gui_v6/profile_view.py
Normal file
@@ -0,0 +1,69 @@
|
||||
"""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()]
|
||||
Reference in New Issue
Block a user