Applique le gabarit sobre/compact/sans défilement à toutes les pages hors éditeur
Généralise le principe déjà en place pour l'édition d'objet (la page n'occupe jamais plus que la hauteur de la fenêtre, seules ses zones internes défilent) à toutes les pages restantes : liste des jeux, tableau de bord d'un jeu, écrans, éléments de jeu, variables, nouvel objet, formulaire de données, tableau des données d'un objet. Seuls l'éditeur d'écran/d'élément et l'aperçu jouable restent en dehors (déjà exclus par leur propre gabarit plein écran, ou pas concernés). Nouveau gabarit générique à une colonne (body.pageBody + .content-page + .scrollArea) sur le même principe que .content-objectEdit, plus une variante .formScroll pour un formulaire long à défilement interne (liste de champs d'un nouvel objet, formulaire de données) tout en gardant les boutons d'action toujours visibles. Les listes/tableaux remplacés par le format dense .fieldsTable (déjà utilisé pour le tableau de bord) pour rester cohérent et afficher plus de lignes à l'écran. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
ac0f003663
commit
59247694d6
@@ -128,6 +128,40 @@ body.objectEditBody > main.content{ flex:1 1 auto; min-height:0; overflow:hidden
|
|||||||
.fieldsTable td input, .fieldsTable td select{ min-width:120px; width:auto; }
|
.fieldsTable td input, .fieldsTable td select{ min-width:120px; width:auto; }
|
||||||
.fieldsTableActions{ display:flex; gap:6px; }
|
.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) ---------- */
|
/* ---------- Éditeur d'écrans (façon Elementor/Bricks) ---------- */
|
||||||
/* La page de l'éditeur d'écran ne doit jamais défiler elle-même : elle
|
/* 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
|
occupe exactement la hauteur de la fenêtre (topbar + zone de travail), et
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% block title %}{{ 'Modifier' if row else 'Ajouter' }} — {{ definition.name }}{% endblock %}
|
{% block title %}{{ 'Modifier' if row else 'Ajouter' }} — {{ definition.name }}{% endblock %}
|
||||||
|
{% block content_class %}content-page{% endblock %}
|
||||||
|
{% block body_class %}pageBody{% endblock %}
|
||||||
{% block breadcrumb %}
|
{% block breadcrumb %}
|
||||||
<li><a href="{{ url_for('game_dashboard', slug=game.slug) }}">{{ game.name }}</a></li>
|
<li><a href="{{ url_for('game_dashboard', slug=game.slug) }}">{{ game.name }}</a></li>
|
||||||
<li><a href="{{ url_for('object_view', slug=game.slug, definition_id=definition.id) }}">{{ definition.name }}</a></li>
|
<li><a href="{{ url_for('object_view', slug=game.slug, definition_id=definition.id) }}">{{ definition.name }}</a></li>
|
||||||
@@ -7,9 +9,10 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1 class="title">{{ 'Modifier l\'entrée #' ~ row.id if row else 'Ajouter une entrée' }} — {{ definition.name }}</h1>
|
<h1 class="title">{{ 'Modifier l\'entrée #' ~ row.id if row else 'Ajouter une entrée' }} — {{ definition.name }}</h1>
|
||||||
<p class="help mb-4">Formulaire généré automatiquement à partir de la définition de cet objet — aucun champ n'est codé en dur ici.</p>
|
<p class="hint mb-4">Formulaire généré automatiquement à partir de la définition de cet objet — aucun champ n'est codé en dur ici.</p>
|
||||||
|
|
||||||
<form method="post" class="box">
|
<form method="post" class="formScroll">
|
||||||
|
<div class="scrollArea">
|
||||||
{% for f in definition.fields %}
|
{% for f in definition.fields %}
|
||||||
{% set col = f.name|colname %}
|
{% set col = f.name|colname %}
|
||||||
{% set current = row[col] if row else none %}
|
{% set current = row[col] if row else none %}
|
||||||
@@ -52,9 +55,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="field">
|
<div class="actionsRow">
|
||||||
<button type="submit" class="button is-primary">{{ 'Enregistrer les modifications' if row else 'Enregistrer en base' }}</button>
|
<button type="submit" class="primary">{{ 'Enregistrer les modifications' if row else 'Enregistrer en base' }}</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% block title %}{{ definition.name }} — {{ game.name }}{% endblock %}
|
{% block title %}{{ definition.name }} — {{ game.name }}{% endblock %}
|
||||||
|
{% block content_class %}content-page{% endblock %}
|
||||||
|
{% block body_class %}pageBody{% endblock %}
|
||||||
{% block breadcrumb %}
|
{% block breadcrumb %}
|
||||||
<li><a href="{{ url_for('game_dashboard', slug=game.slug) }}">{{ game.name }}</a></li>
|
<li><a href="{{ url_for('game_dashboard', slug=game.slug) }}">{{ game.name }}</a></li>
|
||||||
<li class="is-active"><a>{{ definition.name }}</a></li>
|
<li class="is-active"><a>{{ definition.name }}</a></li>
|
||||||
@@ -8,10 +10,10 @@
|
|||||||
<h1 class="title">{{ definition.name }}
|
<h1 class="title">{{ definition.name }}
|
||||||
<a class="button is-small" href="{{ url_for('object_edit', slug=game.slug, definition_id=definition.id) }}" title="Modifier cet objet">✏️</a>
|
<a class="button is-small" href="{{ url_for('object_edit', slug=game.slug, definition_id=definition.id) }}" title="Modifier cet objet">✏️</a>
|
||||||
</h1>
|
</h1>
|
||||||
<p class="help mb-4">Table SQL : {{ definition.table_name }} — {{ definition.fields|length }} champ(s)</p>
|
<p class="hint mb-4">Table SQL : {{ definition.table_name }} — {{ definition.fields|length }} champ(s)</p>
|
||||||
|
|
||||||
{% if referenced_by %}
|
{% if referenced_by %}
|
||||||
<div class="notification is-warning is-light">
|
<div class="warningBanner">
|
||||||
⚠️ D'autres objets ont une relation vers « {{ definition.name }} » :
|
⚠️ D'autres objets ont une relation vers « {{ definition.name }} » :
|
||||||
{{ referenced_by|map(attribute='name')|join(', ') }}.
|
{{ referenced_by|map(attribute='name')|join(', ') }}.
|
||||||
La suppression de cet objet est bloquée tant que ces relations existent.
|
La suppression de cet objet est bloquée tant que ces relations existent.
|
||||||
@@ -19,16 +21,17 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if blocked_row_id %}
|
{% if blocked_row_id %}
|
||||||
<div class="notification is-warning is-light">
|
<div class="warningBanner">
|
||||||
⚠️ Impossible de supprimer l'entrée #{{ blocked_row_id }} : elle est référencée par
|
⚠️ Impossible de supprimer l'entrée #{{ blocked_row_id }} : elle est référencée par
|
||||||
{% for ref in blocked_row_refs %}{{ ref.count }} entrée(s) de « {{ ref.definition_name }} » (champ « {{ ref.field_name }} »){% if not loop.last %}, {% endif %}{% endfor %}.
|
{% for ref in blocked_row_refs %}{{ ref.count }} entrée(s) de « {{ ref.definition_name }} » (champ « {{ ref.field_name }} »){% if not loop.last %}, {% endif %}{% endfor %}.
|
||||||
Modifie ou supprime d'abord ces entrées.
|
Modifie ou supprime d'abord ces entrées.
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<a class="button is-primary is-outlined mb-4" href="{{ url_for('data_new', slug=game.slug, definition_id=definition.id) }}">+ Ajouter une entrée</a>
|
<a class="addBtn" href="{{ url_for('data_new', slug=game.slug, definition_id=definition.id) }}">+ Ajouter une entrée</a>
|
||||||
|
|
||||||
<h2 class="subtitle">Données enregistrées</h2>
|
<h2>Données enregistrées</h2>
|
||||||
|
<div class="scrollArea">
|
||||||
{% if rows %}
|
{% if rows %}
|
||||||
{% macro row_field_display(f, r) %}
|
{% macro row_field_display(f, r) %}
|
||||||
{%- if f.type == 'relation' -%}
|
{%- if f.type == 'relation' -%}
|
||||||
@@ -39,8 +42,8 @@
|
|||||||
{{ r[f.name|colname] }}
|
{{ r[f.name|colname] }}
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
<div class="table-container">
|
<div class="fieldsTableWrap">
|
||||||
<table class="table is-fullwidth is-hoverable dataTable">
|
<table class="table is-fullwidth is-hoverable dataTable fieldsTable">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>#</th>
|
<th>#</th>
|
||||||
@@ -91,8 +94,9 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<p class="help">Aucune donnée enregistrée pour l'instant.</p>
|
<p class="hint">Aucune donnée enregistrée pour l'instant.</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
function openRowDetail(id) {
|
function openRowDetail(id) {
|
||||||
|
|||||||
@@ -1,32 +1,28 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% block title %}Éléments de jeu — {{ game.name }}{% endblock %}
|
{% block title %}Éléments de jeu — {{ game.name }}{% endblock %}
|
||||||
|
{% block content_class %}content-page{% endblock %}
|
||||||
|
{% block body_class %}pageBody{% endblock %}
|
||||||
{% block breadcrumb %}
|
{% block breadcrumb %}
|
||||||
<li><a href="{{ url_for('game_dashboard', slug=game.slug) }}">{{ game.name }}</a></li>
|
<li><a href="{{ url_for('game_dashboard', slug=game.slug) }}">{{ game.name }}</a></li>
|
||||||
<li class="is-active"><a>Éléments de jeu</a></li>
|
<li class="is-active"><a>Éléments de jeu</a></li>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1 class="title">Éléments de jeu</h1>
|
<h1 class="title">Éléments de jeu</h1>
|
||||||
<p class="help mb-4">Un élément de jeu est un conteneur réutilisable.</p>
|
<p class="hint mb-4">Un élément de jeu est un conteneur réutilisable.</p>
|
||||||
|
|
||||||
<form method="post" class="box">
|
<form method="post" class="card">
|
||||||
<div class="columns">
|
<div class="fieldRow">
|
||||||
<div class="column is-narrow" style="width:100px;">
|
<div class="formField" style="flex:0 0 80px;">
|
||||||
<div class="field">
|
<label for="icon">Icône</label>
|
||||||
<label class="label" for="icon">Icône</label>
|
<input type="text" id="icon" name="icon" value="🧩" maxlength="4">
|
||||||
<div class="control"><input class="input" type="text" id="icon" name="icon" value="🧩" maxlength="4"></div>
|
</div>
|
||||||
|
<div class="formField" style="flex:1;">
|
||||||
|
<label for="name">Nom</label>
|
||||||
|
<input type="text" id="name" name="name" placeholder="ex. Personnage, Outil, Carte mail..." required>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="column">
|
<div class="formField">
|
||||||
<div class="field">
|
<label for="bound_definition_id">Objet lié (optionnel)</label>
|
||||||
<label class="label" for="name">Nom</label>
|
|
||||||
<div class="control"><input class="input" type="text" id="name" name="name" placeholder="ex. Personnage, Outil, Carte mail..." required></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="field">
|
|
||||||
<label class="label" for="bound_definition_id">Objet lié (optionnel)</label>
|
|
||||||
<div class="control">
|
|
||||||
<div class="select is-fullwidth">
|
|
||||||
<select id="bound_definition_id" name="bound_definition_id">
|
<select id="bound_definition_id" name="bound_definition_id">
|
||||||
<option value="">(aucun — élément décoratif, sans donnée)</option>
|
<option value="">(aucun — élément décoratif, sans donnée)</option>
|
||||||
{% for d in definitions %}
|
{% for d in definitions %}
|
||||||
@@ -34,43 +30,39 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="actionsRow"><button type="submit" class="primary">+ Créer</button></div>
|
||||||
</div>
|
|
||||||
<div class="field"><button type="submit" class="button is-primary">+ Créer</button></div>
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<h2 class="subtitle">Catalogue</h2>
|
<h2>Catalogue</h2>
|
||||||
|
<div class="scrollArea">
|
||||||
{% if types %}
|
{% if types %}
|
||||||
<div class="table-container">
|
<div class="fieldsTableWrap">
|
||||||
<table class="table is-fullwidth is-hoverable">
|
<table class="table is-fullwidth is-hoverable fieldsTable">
|
||||||
|
<thead><tr><th>Nom</th><th>Usage</th><th></th></tr></thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for t in types %}
|
{% for t in types %}
|
||||||
<tr>
|
<tr>
|
||||||
<td class="is-vcentered">
|
<td>{{ t.icon }} {{ t.name }}</td>
|
||||||
<span class="has-text-weight-semibold">{{ t.icon }} {{ t.name }}</span>
|
<td class="has-text-grey">
|
||||||
<br>
|
{{ usage.get(t.id, 0) }} instance(s)
|
||||||
<span class="is-size-7 has-text-grey">
|
|
||||||
{{ usage.get(t.id, 0) }} instance(s) posée(s) sur des écrans
|
|
||||||
{% if t.bound_definition_id %}
|
{% if t.bound_definition_id %}
|
||||||
{% for d in definitions %}{% if d.id == t.bound_definition_id %} · lié à l'objet « {{ d.name }} »{% endif %}{% endfor %}
|
{% for d in definitions %}{% if d.id == t.bound_definition_id %} · « {{ d.name }} »{% endif %}{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</span>
|
|
||||||
</td>
|
</td>
|
||||||
<td class="is-vcentered has-text-right">
|
<td class="fieldsTableActions">
|
||||||
<div class="buttons is-inline-flex are-small">
|
<a class="button is-small" href="{{ url_for('screen_edit', slug=game.slug, screen_id=t.template_screen_id) }}" title="Modifier le contenu de cet élément de jeu">✏️</a>
|
||||||
<a class="button is-small" href="{{ url_for('screen_edit', slug=game.slug, screen_id=t.template_screen_id) }}" title="Modifier le contenu de cet élément de jeu">✏️ Modifier le contenu</a>
|
|
||||||
<form method="post" action="{{ url_for('element_type_delete', slug=game.slug, element_type_id=t.id) }}"
|
<form method="post" action="{{ url_for('element_type_delete', slug=game.slug, element_type_id=t.id) }}"
|
||||||
onsubmit="return confirm('Supprimer l\'élément de jeu « {{ t.name }} » du catalogue (et tout son contenu) ?');">
|
onsubmit="return confirm('Supprimer l\'élément de jeu « {{ t.name }} » du catalogue (et tout son contenu) ?');">
|
||||||
<button type="submit" class="button is-small is-danger" {{ 'disabled title="Utilisé sur un écran — retire-le des écrans d\'abord"' if usage.get(t.id, 0) > 0 else '' }}>🗑️</button>
|
<button type="submit" class="button is-small is-danger" {{ 'disabled title="Utilisé sur un écran — retire-le des écrans d\'abord"' if usage.get(t.id, 0) > 0 else '' }}>🗑️</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<p class="help">Aucun élément de jeu défini pour l'instant.</p>
|
<p class="hint">Aucun élément de jeu défini pour l'instant.</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% block title %}Variables — {{ game.name }}{% endblock %}
|
{% block title %}Variables — {{ game.name }}{% endblock %}
|
||||||
{% block content_class %}content-wide{% endblock %}
|
{% block content_class %}content-page{% endblock %}
|
||||||
|
{% block body_class %}pageBody{% endblock %}
|
||||||
{% block breadcrumb %}
|
{% block breadcrumb %}
|
||||||
<li><a href="{{ url_for('game_dashboard', slug=game.slug) }}">{{ game.name }}</a></li>
|
<li><a href="{{ url_for('game_dashboard', slug=game.slug) }}">{{ game.name }}</a></li>
|
||||||
<li class="is-active"><a>Variables</a></li>
|
<li class="is-active"><a>Variables</a></li>
|
||||||
@@ -10,9 +11,8 @@
|
|||||||
<p class="hint mb-4">Des propriétés/valeurs communes à tout le jeu (pas attachées à un objet de données précis) — utile par exemple pour une porte ouverte ou non, un niveau débloqué... Une variable peut être lue dans une "Condition de visibilité" (propriétés d'un élément) et modifiée par une action "Modifier une variable" (Logique de la scène).</p>
|
<p class="hint mb-4">Des propriétés/valeurs communes à tout le jeu (pas attachées à un objet de données précis) — utile par exemple pour une porte ouverte ou non, un niveau débloqué... Une variable peut être lue dans une "Condition de visibilité" (propriétés d'un élément) et modifiée par une action "Modifier une variable" (Logique de la scène).</p>
|
||||||
|
|
||||||
<form method="post" action="{{ url_for('create_global_var', slug=game.slug) }}" class="card">
|
<form method="post" action="{{ url_for('create_global_var', slug=game.slug) }}" class="card">
|
||||||
<h3>Nouvelle variable</h3>
|
|
||||||
<div class="fieldRow">
|
<div class="fieldRow">
|
||||||
<div class="formField">
|
<div class="formField" style="flex:1;">
|
||||||
<label for="new-var-name">Nom</label>
|
<label for="new-var-name">Nom</label>
|
||||||
<input type="text" id="new-var-name" name="name" placeholder="ex. porte_ouverte" required autocomplete="off">
|
<input type="text" id="new-var-name" name="name" placeholder="ex. porte_ouverte" required autocomplete="off">
|
||||||
</div>
|
</div>
|
||||||
@@ -33,34 +33,40 @@
|
|||||||
</form>
|
</form>
|
||||||
|
|
||||||
<h2>Variables définies</h2>
|
<h2>Variables définies</h2>
|
||||||
|
<div class="scrollArea">
|
||||||
{% if variables %}
|
{% if variables %}
|
||||||
<div class="list">
|
{% for v in variables %}
|
||||||
|
<form method="post" action="{{ url_for('global_var_edit', slug=game.slug, var_id=v.id) }}" id="varEditForm{{ v.id }}"></form>
|
||||||
|
{% endfor %}
|
||||||
|
<div class="fieldsTableWrap">
|
||||||
|
<table class="table is-fullwidth is-hoverable fieldsTable">
|
||||||
|
<thead><tr><th>Nom</th><th>Type</th><th>Valeur</th><th></th></tr></thead>
|
||||||
|
<tbody>
|
||||||
{% for v in variables %}
|
{% for v in variables %}
|
||||||
<form method="post" action="{{ url_for('global_var_edit', slug=game.slug, var_id=v.id) }}" id="varEditForm{{ v.id }}"></form>
|
<tr>
|
||||||
<div class="listRow">
|
<td>{{ v.name }}</td>
|
||||||
<div class="listRowFlex">
|
<td>
|
||||||
<div class="rowLink">
|
|
||||||
<div class="rowTitle">{{ v.name }}</div>
|
|
||||||
<div class="rowSub">valeur actuelle : {{ v.value if v.value is not none and v.value != '' else '(vide)' }}</div>
|
|
||||||
</div>
|
|
||||||
<div class="rowActions">
|
|
||||||
<select form="varEditForm{{ v.id }}" name="type" aria-label="Type de « {{ v.name }} »">
|
<select form="varEditForm{{ v.id }}" name="type" aria-label="Type de « {{ v.name }} »">
|
||||||
{% for key, val in variable_types.items() %}
|
{% for key, val in variable_types.items() %}
|
||||||
<option value="{{ key }}" {{ 'selected' if v.type == key else '' }}>{{ val.label }}</option>
|
<option value="{{ key }}" {{ 'selected' if v.type == key else '' }}>{{ val.label }}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
<input type="text" form="varEditForm{{ v.id }}" name="value" value="{{ v.value or '' }}" aria-label="Valeur de « {{ v.name }} »" style="width:120px;">
|
</td>
|
||||||
<button type="submit" form="varEditForm{{ v.id }}" class="smallBtn">Enregistrer</button>
|
<td><input type="text" form="varEditForm{{ v.id }}" name="value" value="{{ v.value or '' }}" aria-label="Valeur de « {{ v.name }} »"></td>
|
||||||
|
<td class="fieldsTableActions">
|
||||||
|
<button type="submit" form="varEditForm{{ v.id }}" class="button is-small">Enregistrer</button>
|
||||||
<form method="post" action="{{ url_for('global_var_delete', slug=game.slug, var_id=v.id) }}"
|
<form method="post" action="{{ url_for('global_var_delete', slug=game.slug, var_id=v.id) }}"
|
||||||
onsubmit="return confirm('Supprimer la variable « {{ v.name }} » ? Toute condition de visibilité ou action qui la référence cessera de fonctionner.');">
|
onsubmit="return confirm('Supprimer la variable « {{ v.name }} » ? Toute condition de visibilité ou action qui la référence cessera de fonctionner.');">
|
||||||
<button type="submit" class="smallBtn danger">🗑️</button>
|
<button type="submit" class="button is-small is-danger">🗑️</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</td>
|
||||||
</div>
|
</tr>
|
||||||
</div>
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<p class="hint">Aucune variable pour l'instant — crée la première ci-dessus.</p>
|
<p class="hint">Aucune variable pour l'instant — crée la première ci-dessus.</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
+21
-22
@@ -1,37 +1,35 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% block title %}Forge Engine — Mes jeux{% endblock %}
|
{% block title %}Forge Engine — Mes jeux{% endblock %}
|
||||||
{% block breadcrumb_wrap %}{% endblock %}
|
{% block breadcrumb_wrap %}{% endblock %}
|
||||||
|
{% block content_class %}content-page{% endblock %}
|
||||||
|
{% block body_class %}pageBody{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1 class="title">Mes jeux</h1>
|
<h1 class="title">Mes jeux</h1>
|
||||||
|
|
||||||
<form method="post" action="{{ url_for('games_new') }}" class="box">
|
<form method="post" action="{{ url_for('games_new') }}" class="card">
|
||||||
<div class="field">
|
<div class="fieldRow">
|
||||||
<label class="label" for="name">Nom du nouveau jeu</label>
|
<div class="formField" style="flex:1;">
|
||||||
<div class="field has-addons">
|
<label for="name">Nom du nouveau jeu</label>
|
||||||
<div class="control is-expanded">
|
<input type="text" id="name" name="name" placeholder="ex. CyberQuest RGPD" required>
|
||||||
<input class="input" type="text" id="name" name="name" placeholder="ex. CyberQuest RGPD" required>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="control">
|
<button type="submit" class="primary" style="align-self:flex-end;">+ Créer le jeu</button>
|
||||||
<button type="submit" class="button is-primary">+ Créer le jeu</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<p class="help">Crée un dossier avec index.html / index.css / index.js reliés entre eux, et une base de données dédiée à ce jeu.</p>
|
|
||||||
</div>
|
</div>
|
||||||
|
<p class="hint" style="margin-top:6px;">Crée un dossier avec index.html / index.css / index.js reliés entre eux, et une base de données dédiée à ce jeu.</p>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<h2 class="subtitle">Jeux existants</h2>
|
<h2>Jeux existants</h2>
|
||||||
|
<div class="scrollArea">
|
||||||
{% if games %}
|
{% if games %}
|
||||||
<div class="table-container">
|
<div class="fieldsTableWrap">
|
||||||
<table class="table is-fullwidth is-hoverable">
|
<table class="table is-fullwidth is-hoverable fieldsTable">
|
||||||
|
<thead><tr><th>Nom</th><th>Dossier</th><th></th></tr></thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for g in games %}
|
{% for g in games %}
|
||||||
<tr>
|
<tr>
|
||||||
<td class="is-vcentered">
|
<td><a href="{{ url_for('game_dashboard', slug=g.slug) }}">{{ g.name }}</a></td>
|
||||||
<a href="{{ url_for('game_dashboard', slug=g.slug) }}" class="has-text-weight-semibold">{{ g.name }}</a>
|
<td class="has-text-grey">projects/{{ g.slug }}/</td>
|
||||||
<br><span class="is-size-7 has-text-grey">projects/{{ g.slug }}/</span>
|
<td class="fieldsTableActions">
|
||||||
</td>
|
<form method="post" action="{{ url_for('game_delete', slug=g.slug) }}"
|
||||||
<td class="is-vcentered has-text-right">
|
|
||||||
<form method="post" action="{{ url_for('game_delete', slug=g.slug) }}" class="is-inline-block"
|
|
||||||
onsubmit="return confirm('Supprimer définitivement le jeu « {{ g.name }} » et tout son contenu (dossier + base de données) ?');">
|
onsubmit="return confirm('Supprimer définitivement le jeu « {{ g.name }} » et tout son contenu (dossier + base de données) ?');">
|
||||||
<button type="submit" class="button is-small is-danger" title="Supprimer ce jeu">🗑️</button>
|
<button type="submit" class="button is-small is-danger" title="Supprimer ce jeu">🗑️</button>
|
||||||
</form>
|
</form>
|
||||||
@@ -39,9 +37,10 @@
|
|||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<p class="help">Aucun jeu pour l'instant — crée le premier ci-dessus.</p>
|
<p class="hint">Aucun jeu pour l'instant — crée le premier ci-dessus.</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% block title %}Nouvel objet — {{ game.name }}{% endblock %}
|
{% block title %}Nouvel objet — {{ game.name }}{% endblock %}
|
||||||
|
{% block content_class %}content-page{% endblock %}
|
||||||
|
{% block body_class %}pageBody{% endblock %}
|
||||||
{% block breadcrumb %}
|
{% block breadcrumb %}
|
||||||
<li><a href="{{ url_for('game_dashboard', slug=game.slug) }}">{{ game.name }}</a></li>
|
<li><a href="{{ url_for('game_dashboard', slug=game.slug) }}">{{ game.name }}</a></li>
|
||||||
<li class="is-active"><a>Nouvel objet</a></li>
|
<li class="is-active"><a>Nouvel objet</a></li>
|
||||||
@@ -7,19 +9,19 @@
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
<h1 class="title">Définir un nouvel objet</h1>
|
<h1 class="title">Définir un nouvel objet</h1>
|
||||||
|
|
||||||
<form method="post" class="box" id="objectForm">
|
<form method="post" class="formScroll" id="objectForm">
|
||||||
<div class="field">
|
<div class="formField">
|
||||||
<label class="label" for="object_name">Nom de l'objet (ex. Personnage, Niveau, Question...)</label>
|
<label for="object_name">Nom de l'objet (ex. Personnage, Niveau, Question...)</label>
|
||||||
<div class="control"><input class="input" type="text" id="object_name" name="object_name" required></div>
|
<input type="text" id="object_name" name="object_name" required>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h3 class="title is-6">Champs</h3>
|
<h3>Champs</h3>
|
||||||
|
<div class="scrollArea">
|
||||||
<div id="fieldsList"></div>
|
<div id="fieldsList"></div>
|
||||||
<button type="button" class="button is-outlined is-fullwidth mb-4" id="btnAddField">+ Ajouter un champ</button>
|
|
||||||
|
|
||||||
<div class="field">
|
|
||||||
<button type="submit" class="button is-primary">Créer l'objet</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
<button type="button" class="button is-outlined is-fullwidth" id="btnAddField">+ Ajouter un champ</button>
|
||||||
|
|
||||||
|
<div class="actionsRow"><button type="submit" class="primary">Créer l'objet</button></div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<template id="fieldRowTemplate">
|
<template id="fieldRowTemplate">
|
||||||
|
|||||||
+22
-22
@@ -1,5 +1,7 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% block title %}Écrans — {{ game.name }}{% endblock %}
|
{% block title %}Écrans — {{ game.name }}{% endblock %}
|
||||||
|
{% block content_class %}content-page{% endblock %}
|
||||||
|
{% block body_class %}pageBody{% endblock %}
|
||||||
{% block breadcrumb %}
|
{% block breadcrumb %}
|
||||||
<li><a href="{{ url_for('game_dashboard', slug=game.slug) }}">{{ game.name }}</a></li>
|
<li><a href="{{ url_for('game_dashboard', slug=game.slug) }}">{{ game.name }}</a></li>
|
||||||
<li class="is-active"><a>Écrans</a></li>
|
<li class="is-active"><a>Écrans</a></li>
|
||||||
@@ -7,39 +9,37 @@
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
<h1 class="title">Écrans du jeu</h1>
|
<h1 class="title">Écrans du jeu</h1>
|
||||||
|
|
||||||
<form method="post" action="{{ url_for('screens_new', slug=game.slug) }}" class="box">
|
<form method="post" action="{{ url_for('screens_new', slug=game.slug) }}" class="card">
|
||||||
<div class="field">
|
<div class="fieldRow">
|
||||||
<label class="label" for="name">Nom du nouvel écran</label>
|
<div class="formField" style="flex:1;">
|
||||||
<div class="field has-addons">
|
<label for="name">Nom du nouvel écran</label>
|
||||||
<div class="control is-expanded">
|
<input type="text" id="name" name="name" placeholder="ex. Accueil, Formulaire d'inscription, Scène 1..." required>
|
||||||
<input class="input" type="text" id="name" name="name" placeholder="ex. Accueil, Formulaire d'inscription, Scène 1..." required>
|
|
||||||
</div>
|
|
||||||
<div class="control">
|
|
||||||
<button type="submit" class="button is-primary">+ Créer l'écran</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<button type="submit" class="primary" style="align-self:flex-end;">+ Créer l'écran</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
{% if request.args.get('blocked_screen') %}
|
{% if request.args.get('blocked_screen') %}
|
||||||
<div class="notification is-warning is-light">
|
<div class="warningBanner">
|
||||||
⚠️ Suppression impossible : au moins un autre écran a un bouton qui cible précisément celui-ci. Retire d'abord cette action.
|
⚠️ Suppression impossible : au moins un autre écran a un bouton qui cible précisément celui-ci. Retire d'abord cette action.
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<h2 class="subtitle">Enchaînement des écrans</h2>
|
<h2>Enchaînement des écrans</h2>
|
||||||
|
<div class="scrollArea">
|
||||||
{% if screen_list %}
|
{% if screen_list %}
|
||||||
<div class="table-container">
|
<div class="fieldsTableWrap">
|
||||||
<table class="table is-fullwidth is-hoverable">
|
<table class="table is-fullwidth is-hoverable fieldsTable">
|
||||||
|
<thead><tr><th>#</th><th>Nom</th><th></th></tr></thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for s in screen_list %}
|
{% for s in screen_list %}
|
||||||
<tr>
|
<tr>
|
||||||
<td class="is-vcentered">
|
<td>{{ loop.index }}</td>
|
||||||
<a href="{{ url_for('screen_edit', slug=game.slug, screen_id=s.id) }}">{{ loop.index }}. {{ s.name }}</a>
|
<td>
|
||||||
{% if loop.first %} <span class="tag is-info is-light">★ Écran de départ</span>{% endif %}
|
<a href="{{ url_for('screen_edit', slug=game.slug, screen_id=s.id) }}">{{ s.name }}</a>
|
||||||
|
{% if loop.first %} <span class="tag is-info is-light">★ Départ</span>{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td class="is-vcentered has-text-right">
|
<td class="fieldsTableActions">
|
||||||
<div class="buttons is-inline-flex are-small">
|
|
||||||
<form method="post" action="{{ url_for('screen_move', slug=game.slug, screen_id=s.id) }}"><input type="hidden" name="direction" value="up"><button type="submit" class="button is-small" {{ 'disabled' if loop.first else '' }}>↑</button></form>
|
<form method="post" action="{{ url_for('screen_move', slug=game.slug, screen_id=s.id) }}"><input type="hidden" name="direction" value="up"><button type="submit" class="button is-small" {{ 'disabled' if loop.first else '' }}>↑</button></form>
|
||||||
<form method="post" action="{{ url_for('screen_move', slug=game.slug, screen_id=s.id) }}"><input type="hidden" name="direction" value="down"><button type="submit" class="button is-small" {{ 'disabled' if loop.last else '' }}>↓</button></form>
|
<form method="post" action="{{ url_for('screen_move', slug=game.slug, screen_id=s.id) }}"><input type="hidden" name="direction" value="down"><button type="submit" class="button is-small" {{ 'disabled' if loop.last else '' }}>↓</button></form>
|
||||||
<a class="button is-small" href="{{ url_for('screen_edit', slug=game.slug, screen_id=s.id) }}">✏️</a>
|
<a class="button is-small" href="{{ url_for('screen_edit', slug=game.slug, screen_id=s.id) }}">✏️</a>
|
||||||
@@ -47,14 +47,14 @@
|
|||||||
onsubmit="return confirm('Supprimer l\'écran « {{ s.name }} » et tous ses éléments ?');">
|
onsubmit="return confirm('Supprimer l\'écran « {{ s.name }} » et tous ses éléments ?');">
|
||||||
<button type="submit" class="button is-small is-danger">🗑️</button>
|
<button type="submit" class="button is-small is-danger">🗑️</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<p class="help">Aucun écran pour l'instant — crée le premier ci-dessus.</p>
|
<p class="hint">Aucun écran pour l'instant — crée le premier ci-dessus.</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
Reference in New Issue
Block a user