From 2051b375ace45b3ea5007047c0b51afd664de8f1 Mon Sep 17 00:00:00 2001 From: william Date: Tue, 25 Aug 2026 10:58:49 +0200 Subject: [PATCH] =?UTF-8?q?Passe=20toutes=20les=20pages=20restantes=20en?= =?UTF-8?q?=20deux=20colonnes=20(cr=C3=A9er=20=C3=A0=20gauche,=20contenu?= =?UTF-8?q?=20=C3=A0=20droite)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Généralise le principe déjà utilisé pour le tableau de bord et l'édition d'objet à toutes les pages restantes : liste des jeux, écrans, éléments de jeu, variables, nouvel objet, formulaire de données, tableau des données d'un objet - colonne de gauche pour créer/agir, colonne de droite pour ce qui existe déjà, chaque colonne défilant pour son propre compte. Pour un formulaire qui doit rester UN SEUL
à cheval sur les deux colonnes (nouvel objet : nom à gauche, champs à droite ; formulaire de données : bouton Enregistrer à gauche, champs à droite), nouvelle classe .formPassthrough ("display:contents") : le ne devient pas lui-même une boîte dans la mise en page flex, seul .twoCol à l'intérieur compte. Supprime au passage .content-page/.formScroll/body.pageBody (le gabarit à une colonne introduit au tour précédent, plus utilisé nulle part) et .list/.listRow/.listRowFlex/.rowTitle/.rowSub/.rowActions/.addBtn (les cartes à deux lignes remplacées par les tableaux denses et la nav compacte) - du CSS mort plutôt que deux systèmes qui se chevauchent. Co-Authored-By: Claude Sonnet 5 --- static/style.css | 61 +++----------- templates/data_form.html | 107 ++++++++++++++----------- templates/data_list.html | 146 ++++++++++++++++++---------------- templates/element_types.html | 113 +++++++++++++------------- templates/game_variables.html | 119 +++++++++++++-------------- templates/index.html | 75 ++++++++--------- templates/object_form.html | 32 +++++--- templates/screens_list.html | 90 +++++++++++---------- 8 files changed, 374 insertions(+), 369 deletions(-) diff --git a/static/style.css b/static/style.css index 2fafe8c5..014e4160 100644 --- a/static/style.css +++ b/static/style.css @@ -33,23 +33,11 @@ button{ background:var(--panel2); border:1px solid var(--border); color:var(--te button.primary{ background:var(--accent); border-color:var(--accent); color:#fff; font-weight:600; } button.smallBtn{ padding:5px 10px; font-size:11.5px; } button.danger{ color:var(--danger); border-color:rgba(226,104,95,.4); } -.addBtn{ display:inline-block; margin:10px 0; padding:9px 14px; border-radius:6px; border:1px dashed var(--border); color:var(--accent); text-decoration:none; font-size:13px; } .actionsRow{ margin-top:16px; } -.list{ display:flex; flex-direction:column; gap:4px; } -.listRow{ display:block; padding:7px 10px; border:1px solid var(--border); border-radius:6px; background:var(--panel); text-decoration:none; color:var(--text); } -.listRow:hover{ background:var(--panel2); } -.listRowFlex{ display:flex; align-items:center; justify-content:space-between; gap:10px; } -.listRowFlex .rowLink{ flex:1; text-decoration:none; color:var(--text); } -.listRowFlex form{ margin:0; } -.rowTitle{ font-size:13px; } -.rowSub{ font-size:10.5px; color:var(--text-dim); margin-top:1px; } -.rowActions{ display:flex; gap:6px; align-items:center; } - /* Nav compacte à une seule ligne (icône + libellé) — pour une liste - d'actions fixe (ex. tableau de bord d'un jeu) où le sous-titre de - .listRow prendrait trop de place utile pour rien : sobre et dense plutôt - que "carte" explicative. */ + d'actions fixe (ex. colonne "Créer" du tableau de bord d'un jeu) : sobre + et dense plutôt qu'une carte à deux lignes. */ .navList{ display:flex; flex-direction:column; gap:3px; } .navRow{ display:flex; align-items:center; gap:8px; padding:7px 10px; border:1px solid var(--border); border-radius:6px; background:var(--panel); text-decoration:none; color:var(--text); font-size:12.5px; } .navRow:hover{ background:var(--panel2); border-color:var(--accent); } @@ -112,7 +100,16 @@ body.objectEditBody > .topbar, body.objectEditBody > .breadcrumbBar{ flex:0 0 au body.objectEditBody > main.content{ flex:1 1 auto; min-height:0; overflow:hidden; display:flex; flex-direction:column; } .content-objectEdit{ width:100%; display:flex; flex-direction:column; min-height:0; } -.content-objectEdit > h1, .content-objectEdit > .hint, .content-objectEdit > form{ flex:0 0 auto; } +.content-objectEdit > h1, .content-objectEdit > .hint, .content-objectEdit > form, .content-objectEdit > .warningBanner{ flex:0 0 auto; } + +/* Un qui doit envelopper les DEUX colonnes à la fois (un seul + formulaire soumis ensemble, ex. object_form.html : nom de l'objet à + gauche, liste de champs à droite) ne doit pas devenir lui-même une boîte + dans la mise en page flex — sinon .twoCol à l'intérieur perd la hauteur + disponible qu'il doit occuper. "display:contents" le rend transparent : + .twoCol se comporte comme s'il était directement enfant de + .content-objectEdit. */ +.formPassthrough{ display:contents; } .content-objectEdit .twoCol{ flex:1 1 auto; min-height:0; align-items:stretch; } .content-objectEdit .colLeft{ overflow-y:auto; height:100%; } .content-objectEdit .colRight{ display:flex; flex-direction:column; min-height:0; height:100%; } @@ -128,40 +125,6 @@ body.objectEditBody > main.content{ flex:1 1 auto; min-height:0; overflow:hidden .fieldsTable td input, .fieldsTable td select{ min-width:120px; width:auto; } .fieldsTableActions{ display:flex; gap:6px; } -/* ---------- Gabarit générique "page classique" (toutes les pages sauf - l'éditeur d'écran/d'élément et l'aperçu jouable) : même principe que - body.objectEditBody ci-dessus, mais à UNE colonne — un en-tête fixe - (titre, formulaire de création...) suivi d'UNE zone qui défile pour son - propre compte (.scrollArea), jamais la page elle-même. Permet d'afficher - beaucoup de lignes (jeux, écrans, objets, variables, données...) sans - perdre le formulaire de création ou le fil d'Ariane hors de l'écran. */ -body.pageBody{ display:flex; flex-direction:column; height:100vh; margin:0; overflow:hidden; } -body.pageBody > .topbar, body.pageBody > .breadcrumbBar{ flex:0 0 auto; } -body.pageBody > main.content{ flex:1 1 auto; min-height:0; overflow:hidden; display:flex; flex-direction:column; } - -.content-page{ width:100%; display:flex; flex-direction:column; min-height:0; flex:1 1 auto; } -.content-page > *{ flex:0 0 auto; } -.content-page > .scrollArea{ flex:1 1 auto; min-height:0; overflow-y:auto; } - -/* Cas d'un formulaire long à champs dynamiques (ex. object_form.html) : le - FORMULAIRE lui-même doit grandir pour occuper l'espace restant, et - seule sa liste de champs (.scrollArea, à l'intérieur) défile — le champ - "nom" et les boutons "+ Ajouter"/"Créer" restent toujours visibles. */ -.content-page > form.formScroll{ flex:1 1 auto; min-height:0; display:flex; flex-direction:column; } -.formScroll > *{ flex:0 0 auto; } -.formScroll > .scrollArea{ flex:1 1 auto; min-height:0; overflow-y:auto; } - -@media (max-width: 820px){ - /* Même logique de repli que .content-objectEdit : sous cette largeur, - mieux vaut une page qui défile normalement qu'une zone interne trop - comprimée. */ - body.pageBody{ height:auto; overflow:visible; } - body.pageBody > main.content{ overflow:visible; } - .content-page > .scrollArea{ overflow:visible; } - .content-page > form.formScroll{ flex:none; } - .formScroll > .scrollArea{ overflow:visible; } -} - /* ---------- Éditeur d'écrans (façon Elementor/Bricks) ---------- */ /* La page de l'éditeur d'écran ne doit jamais défiler elle-même : elle occupe exactement la hauteur de la fenêtre (topbar + zone de travail), et diff --git a/templates/data_form.html b/templates/data_form.html index 366d2e62..88cc759c 100644 --- a/templates/data_form.html +++ b/templates/data_form.html @@ -1,7 +1,7 @@ {% extends "base.html" %} {% block title %}{{ 'Modifier' if row else 'Ajouter' }} — {{ definition.name }}{% endblock %} -{% block content_class %}content-page{% endblock %} -{% block body_class %}pageBody{% endblock %} +{% block content_class %}content-wide content-objectEdit{% endblock %} +{% block body_class %}objectEditBody{% endblock %} {% block breadcrumb %}
  • {{ game.name }}
  • {{ definition.name }}
  • @@ -9,56 +9,67 @@ {% endblock %} {% block content %}

    {{ 'Modifier l\'entrée #' ~ row.id if row else 'Ajouter une entrée' }} — {{ definition.name }}

    -

    Formulaire généré automatiquement à partir de la définition de cet objet — aucun champ n'est codé en dur ici.

    - -
    - {% for f in definition.fields %} - {% set col = f.name|colname %} - {% set current = row[col] if row else none %} -
    - -
    - - {% if f.type == 'texte' %} - - - {% elif f.type == 'texte_long' %} - - - {% elif f.type == 'nombre_entier' %} - - - {% elif f.type == 'nombre_decimal' %} - - - {% elif f.type == 'booleen' %} - - - {% elif f.type == 'date' %} - - - {% elif f.type == 'relation' %} - {% set current_rel = row[col ~ '_id'] if row else none %} -
    - -
    - {% if not relation_options.get(f.id) %} -

    Aucune entrée n'existe encore pour l'objet lié — crée-en une d'abord si tu veux pouvoir la sélectionner ici.

    - {% endif %} - {% endif %} + +
    +
    +

    Objet

    +
    +

    Formulaire généré automatiquement à partir de la définition de « {{ definition.name }} » — aucun champ n'est codé en dur ici.

    +
    + +
    +

    ← Retour à « {{ definition.name }} »

    - {% endfor %} -
    -
    - +
    +

    Champs

    +
    + {% for f in definition.fields %} + {% set col = f.name|colname %} + {% set current = row[col] if row else none %} +
    + +
    + + {% if f.type == 'texte' %} + + + {% elif f.type == 'texte_long' %} + + + {% elif f.type == 'nombre_entier' %} + + + {% elif f.type == 'nombre_decimal' %} + + + {% elif f.type == 'booleen' %} + + + {% elif f.type == 'date' %} + + + {% elif f.type == 'relation' %} + {% set current_rel = row[col ~ '_id'] if row else none %} +
    + +
    + {% if not relation_options.get(f.id) %} +

    Aucune entrée n'existe encore pour l'objet lié — crée-en une d'abord si tu veux pouvoir la sélectionner ici.

    + {% endif %} + {% endif %} +
    +
    + {% endfor %} +
    +
    {% endblock %} diff --git a/templates/data_list.html b/templates/data_list.html index 285d1cb8..0f9855e1 100644 --- a/templates/data_list.html +++ b/templates/data_list.html @@ -1,7 +1,7 @@ {% extends "base.html" %} {% block title %}{{ definition.name }} — {{ game.name }}{% endblock %} -{% block content_class %}content-page{% endblock %} -{% block body_class %}pageBody{% endblock %} +{% block content_class %}content-wide content-objectEdit{% endblock %} +{% block body_class %}objectEditBody{% endblock %} {% block breadcrumb %}
  • {{ game.name }}
  • {{ definition.name }}
  • @@ -28,74 +28,84 @@
    {% endif %} -+ Ajouter une entrée - -

    Données enregistrées

    -
    -{% if rows %} -{% macro row_field_display(f, r) %} -{%- if f.type == 'relation' -%} -{{ relation_labels.get(f.id, {}).get(r[(f.name|colname) ~ '_id'], '—') }} -{%- elif f.type == 'booleen' -%} -{{ 'Oui' if r[f.name|colname] else 'Non' }} -{%- else -%} -{{ r[f.name|colname] }} -{%- endif -%} -{% endmacro %} -
    - - - - - {% for f in definition.fields %}{% endfor %} - - - - - {% for r in rows %} - - - {% for f in definition.fields %} - - {% endfor %} - - - {% endfor %} - -
    #{{ f.name }}
    {{ r.id }}{{ row_field_display(f, r) }} -
    - - ✏️ -
    - -
    -
    -
    -
    - -{% for r in rows %} - + +
    +

    Données enregistrées

    + {% if rows %} + {% macro row_field_display(f, r) %} + {%- if f.type == 'relation' -%} + {{ relation_labels.get(f.id, {}).get(r[(f.name|colname) ~ '_id'], '—') }} + {%- elif f.type == 'booleen' -%} + {{ 'Oui' if r[f.name|colname] else 'Non' }} + {%- else -%} + {{ r[f.name|colname] }} + {%- endif -%} + {% endmacro %} +
    + + + + + {% for f in definition.fields %}{% endfor %} + + + + + {% for r in rows %} + + + {% for f in definition.fields %} + + {% endfor %} + + + {% endfor %} + +
    #{{ f.name }}
    {{ r.id }}{{ row_field_display(f, r) }} +
    + + ✏️ +
    + +
    +
    +
    +
    + + {% for r in rows %} + + {% endfor %} + {% else %} +

    Aucune donnée enregistrée pour l'instant.

    + {% endif %}
    -
    -{% endfor %} -{% else %} -

    Aucune donnée enregistrée pour l'instant.

    -{% endif %}