fix(gui): make admin config responsive and mask editor usable

This commit is contained in:
2026-06-15 09:53:56 +02:00
parent 269b9e0e13
commit 696f6bf27c
4 changed files with 949 additions and 232 deletions

View File

@@ -2,8 +2,9 @@
Reproduit l'identité de ``docs/ui_mockup_v6.html`` : shell étroit, header avec
identité produit + version + statut licence + liseré accent, barre d'onglets
custom (pas CTkTabview brut), navigation par recréation du contenu, changement
de thème à chaud. La logique (runner moteur, config, licence) est inchangée.
custom (pas CTkTabview brut), navigation par panneaux mis en cache après leur
première ouverture visible, changement de thème à chaud. La logique (runner
moteur, config, licence) est inchangée.
La fenêtre n'est créée qu'à l'instanciation de :class:`AnonymisationApp`.
"""
@@ -41,6 +42,8 @@ class AnonymisationApp(ctk.CTk):
self._config = ConfigState()
self._active = "use"
self._tab_buttons: dict = {}
self._tab_frames: dict = {}
self._visible_tab = None
self.title("Pseudonymisation de vos documents")
self.geometry("820x880")
@@ -130,29 +133,33 @@ class AnonymisationApp(ctk.CTk):
# -- contenu ----------------------------------------------------------
def _show(self, key: str) -> None:
self._active = key
self._refresh_tabbar()
for child in self._content.winfo_children():
child.destroy()
def _create_tab(self, key: str):
p = self._palette
status = self._safe_local_status()
if key == "use":
tab = UsageTab(
return UsageTab(
self._content,
palette=p,
config_provider=lambda: self._config,
on_theme_change=self.set_theme,
current_theme=self._theme_name,
)
elif key == "cfg":
tab = ConfigTab(self._content, palette=p, state=self._config)
else:
tab = AboutTab(
self._content,
palette=p,
status=status,
theme_name=self._theme_name,
license_client=self._license_client,
)
tab.pack(fill="both", expand=True)
if key == "cfg":
return ConfigTab(self._content, palette=p, state=self._config)
return AboutTab(
self._content,
palette=p,
status=status,
theme_name=self._theme_name,
license_client=self._license_client,
)
def _show(self, key: str) -> None:
self._active = key
self._refresh_tabbar()
if self._visible_tab is not None:
self._tab_frames[self._visible_tab].pack_forget()
if key not in self._tab_frames:
self._tab_frames[key] = self._create_tab(key)
self._tab_frames[key].pack(fill="both", expand=True)
self._visible_tab = key

View File

@@ -25,6 +25,13 @@ class ConfigState:
enable_gliner: bool = False
output_dir: Optional[Path] = None
ogc_label: Optional[str] = None
manual_mask_required: bool = False
manual_mask_template: Optional[Path] = None
mask_color: str = "#000000"
mask_marker_style: str = "brackets"
mask_margin_x: int = 2
mask_margin_y: int = 1
mask_rounded_corners: bool = False
def to_engine_settings(self, config_path: Optional[Path] = None) -> EngineSettings:
return EngineSettings(

File diff suppressed because it is too large Load Diff

View File

@@ -2,7 +2,7 @@
from __future__ import annotations
from gui_v6.tabs.tab_config import CONFIG_MOCKUP_SECTIONS
from gui_v6.tabs.tab_config import CONFIG_INTERACTION_CONTRACT, CONFIG_MOCKUP_SECTIONS
def test_config_mockup_sections_cover_admin_surface():
@@ -13,6 +13,8 @@ def test_config_mockup_sections_cover_admin_surface():
"Données à détecter",
"Termes à toujours conserver",
"Termes à toujours masquer",
"Masque manuel obligatoire",
"Template de masque manuel",
],
"masquage": [
"Couleur de masquage (PDF)",
@@ -20,7 +22,23 @@ def test_config_mockup_sections_cover_admin_surface():
"Épaisseur du masque",
"Codes de remplacement",
"Masques de zones fixes",
"Éditeur interactif de masques",
],
"partage": ["Exporter la configuration", "Importer une configuration"],
"regles": ["Règles actives", "Testeur de règle"],
}
def test_config_interaction_contract_prebuilds_panels_and_mask_editor():
assert CONFIG_INTERACTION_CONTRACT["subtabs"] == "prebuilt_panels"
assert CONFIG_INTERACTION_CONTRACT["reglages_columns"] == 3
assert CONFIG_INTERACTION_CONTRACT["mask_editor"] == [
"open_pdf",
"draw_rectangle",
"delete_rectangle_on_click",
"zoom",
"save_template_json",
"load_template_json_or_yaml",
"clear_page",
"apply_template_selection",
]