diff --git a/app_new/core/routes/admin.py b/app_new/core/routes/admin.py index f8679c5..1fd7ff1 100644 --- a/app_new/core/routes/admin.py +++ b/app_new/core/routes/admin.py @@ -452,6 +452,7 @@ def template_debug_preview(): from jinja2 import ChoiceLoader, FileSystemLoader, TemplateNotFound, ChainableUndefined relative_path = (request.args.get('path') or '').strip() + demo_mode = request.args.get('demo', '1') != '0' files, _ = _template_inventory() item = next((candidate for candidate in files if candidate['path'] == relative_path), None) if not item: @@ -481,12 +482,44 @@ def template_debug_preview(): # Reproduire les variables globales Flask (current_user, config, # request...) sans injecter d'objet métier réel dans la prévisualisation. current_app.update_template_context(preview_context) + if demo_mode: + from types import SimpleNamespace + + class DemoObject(SimpleNamespace): + def __getattr__(self, name): + return '' + + demo_room = DemoObject(id=12, name='B102', code='B102', full_name='Bâtiment principal — Zone Anglais — B102') + demo_equipment = DemoObject( + id=42, name='Luminaire LED central', code='ECL-0042', + full_path='Bâtiment principal / Zone Anglais / B102 / Éclairage', + room=demo_room, status='en_service', status_label='En service', + ) + preview_context.update({ + 'current_user': DemoObject(id=1, username='demo.admin', full_name='Administrateur démo', role='admin', role_label='Administrateur système', is_authenticated=True), + 'stats': DemoObject(alerts_unread=3, interventions_pending=4, equipments=128), + 'unread': 3, + 'alerts': [DemoObject(id=1, title='Luminaire défaillant', message='Une intervention est à traiter.', level='warning')], + 'interventions': [DemoObject(id=39, title='Remplacement du luminaire', status='en_cours', status_label='En cours', room=demo_room, equipment=demo_equipment)], + 'intervention': DemoObject(id=39, title='Remplacement du luminaire', type='curatif', status='en_cours', status_label='En cours', room=demo_room, equipment=demo_equipment), + 'rooms': [demo_room, DemoObject(id=13, name='B103', code='B103', full_name='Bâtiment principal — Zone Anglais — B103')], + 'equipments': [demo_equipment, DemoObject(id=43, name='Prise murale fond de salle', code='ELEC-0043', room=demo_room)], + 'categories': [DemoObject(id=1, name='Éclairage'), DemoObject(id=2, name='Prises')], + 'buildings': [DemoObject(id=1, name='Bâtiment principal')], + 'zones': [DemoObject(id=1, name='Zone Anglais')], + 'messages': [DemoObject(subject='Demande de réparation', sender='Vie scolaire', body_preview='Une chaise est cassée en B102.')], + 'mails': [DemoObject(subject='Maintenance urgente', sender='service@exemple.fr', received_at='21/08/2026 08:15')], + 'tasks': [DemoObject(id=7, name='Contrôle mensuel des luminaires', periodicity='Mensuelle', duration_minutes=30)], + 'lots': [DemoObject(id=3, name='Éclairage intérieur', category=DemoObject(name='Éclairage'))], + 'companies': [DemoObject(id=2, name='Entreprise Démo Maintenance')], + }) rendered = template.render(**preview_context) except (TemplateNotFound, Exception) as exc: render_error = f'{type(exc).__name__}: {exc}' return render_template('admin/template_preview.html', template=item, - source=source, rendered=rendered, render_error=render_error) + source=source, rendered=rendered, render_error=render_error, + demo_mode=demo_mode) @admin_bp.route('/debug/templates/mark', methods=['POST']) diff --git a/app_new/templates/admin/template_debug.html b/app_new/templates/admin/template_debug.html index 4f864e3..f50521f 100644 --- a/app_new/templates/admin/template_debug.html +++ b/app_new/templates/admin/template_debug.html @@ -81,7 +81,7 @@ {% else %}Masqué probablement{% endif %} {{ template.hash[:10] }} - Prévisualiser + Prévisualiser
diff --git a/app_new/templates/admin/template_preview.html b/app_new/templates/admin/template_preview.html index 2b899b0..65172ad 100644 --- a/app_new/templates/admin/template_preview.html +++ b/app_new/templates/admin/template_preview.html @@ -10,6 +10,17 @@ Retour à l’audit +
+ + {% if demo_mode %}Données fictives actives. Le rendu utilise un contexte GMAO de démonstration, sans écriture en base.{% else %}Contexte vide. Les variables métier absentes sont tolérées.{% endif %} + + {% if demo_mode %} + Tester sans données + {% else %} + Charger les données fictives + {% endif %} +
+ {% if render_error %}
Rendu incomplet diff --git a/tests/integration/test_intervention_location_and_template_audit.py b/tests/integration/test_intervention_location_and_template_audit.py index 2924282..9e2e839 100644 --- a/tests/integration/test_intervention_location_and_template_audit.py +++ b/tests/integration/test_intervention_location_and_template_audit.py @@ -10,10 +10,11 @@ def test_template_audit_can_mark_and_restore_without_deleting(authenticated_clie assert 'Identiques' in response.get_data(as_text=True) assert 'Divergents' in response.get_data(as_text=True) - response = authenticated_client.get('/admin/debug/templates/preview?path=templates%2Fadmin%2Ftemplate_debug.html') + response = authenticated_client.get('/admin/debug/templates/preview?path=templates%2Fadmin%2Ftemplate_debug.html&demo=1') assert response.status_code == 200 assert 'Prévisualisation du template' in response.get_data(as_text=True) assert 'sandbox' in response.get_data(as_text=True) + assert 'Données fictives actives' in response.get_data(as_text=True) response = authenticated_client.post('/admin/debug/templates/mark', data={ 'path': template_path,