mirror of
https://forge.chapril.org/tykayn/osm-commerces
synced 2025-10-04 17:04:53 +02:00
up wiki controller
This commit is contained in:
parent
2f49ef6479
commit
391a212034
13 changed files with 1271297 additions and 866 deletions
|
@ -18,13 +18,14 @@ body {
|
|||
#qrcode {
|
||||
margin-bottom: 8rem;
|
||||
}
|
||||
input[data-important]{
|
||||
border-color: #7a8fbb ;
|
||||
border-left-width: 5px ;
|
||||
|
||||
input[data-important] {
|
||||
border-color: #7a8fbb;
|
||||
border-left-width: 5px;
|
||||
}
|
||||
|
||||
input[data-important]:before{
|
||||
content : ">" !important ;
|
||||
input[data-important]:before {
|
||||
content: ">" !important;
|
||||
}
|
||||
|
||||
.filled, .good_filled {
|
||||
|
@ -32,7 +33,7 @@ input[data-important]:before{
|
|||
color: #082b0a !important;
|
||||
}
|
||||
|
||||
.filled:hover , .good_filled:hover {
|
||||
.filled:hover, .good_filled:hover {
|
||||
background-color: #d9ffd1 !important;
|
||||
}
|
||||
|
||||
|
@ -174,13 +175,18 @@ table tbody {
|
|||
overflow: auto;
|
||||
}
|
||||
|
||||
#table_container, .table-container, #table-container{
|
||||
max-height: 700px;
|
||||
overflow: auto;
|
||||
display: block;
|
||||
border: solid 3px rgb(255, 255, 255);
|
||||
#table_container, .table-container, #table-container {
|
||||
max-height: 700px;
|
||||
overflow: auto;
|
||||
display: block;
|
||||
border: solid 3px rgb(255, 255, 255);
|
||||
}
|
||||
|
||||
#citySuggestions{
|
||||
#citySuggestions {
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
body .card:hover {
|
||||
transform: none !important;
|
||||
box-shadow: none !important;
|
||||
}
|
104
public/osm_fr_groups.json
Normal file
104
public/osm_fr_groups.json
Normal file
|
@ -0,0 +1,104 @@
|
|||
{
|
||||
"last_updated": "2025-08-22T17:10:41.058478",
|
||||
"local_groups": [
|
||||
{
|
||||
"name": "Liste des groupes locaux se réunissant régulièrement",
|
||||
"url": "https://framacalc.org/osm-groupes-locaux",
|
||||
"description": "",
|
||||
"type": "local_group"
|
||||
},
|
||||
{
|
||||
"name": "Carte des groupes locaux se réunissant régulièrement",
|
||||
"url": "https://umap.openstreetmap.fr/fr/map/groupes-locaux-openstreetmap_152488",
|
||||
"description": "",
|
||||
"type": "local_group"
|
||||
}
|
||||
],
|
||||
"working_groups": [
|
||||
{
|
||||
"name": "Que venir faire au sein de l'association ?",
|
||||
"url": "https://forum.openstreetmap.fr/t/que-venir-faire-au-sein-de-lassociation/15454",
|
||||
"description": "",
|
||||
"category": "Général",
|
||||
"type": "working_group"
|
||||
},
|
||||
{
|
||||
"name": "GT Inclusivité",
|
||||
"url": "https://wiki.openstreetmap.org/wiki/France/OSM-FR/Groupes_de_travail#GT_Inclusivité",
|
||||
"description": "",
|
||||
"category": "Général",
|
||||
"type": "working_group"
|
||||
},
|
||||
{
|
||||
"name": "GT Technique",
|
||||
"url": "https://wiki.openstreetmap.org/wiki/France/OSM-FR/Groupes_de_travail#GT_Technique",
|
||||
"description": "",
|
||||
"category": "Général",
|
||||
"type": "working_group"
|
||||
},
|
||||
{
|
||||
"name": "GT Communication externe",
|
||||
"url": "https://wiki.openstreetmap.org/wiki/France/OSM-FR/Groupes_de_travail#GT_Communication",
|
||||
"description": "",
|
||||
"category": "Général",
|
||||
"type": "working_group"
|
||||
},
|
||||
{
|
||||
"name": "GT Animation de la communauté",
|
||||
"url": "https://wiki.openstreetmap.org/wiki/France/OSM-FR/Groupes_de_travail#GT_Animation_de_la_communauté",
|
||||
"description": "",
|
||||
"category": "Général",
|
||||
"type": "working_group"
|
||||
},
|
||||
{
|
||||
"name": "GT Communautés locales",
|
||||
"url": "https://wiki.openstreetmap.org/wiki/France/OSM-FR/Groupes_de_travail#GT_Communautés_locales",
|
||||
"description": "",
|
||||
"category": "Général",
|
||||
"type": "working_group"
|
||||
},
|
||||
{
|
||||
"name": "GT International",
|
||||
"url": "https://wiki.openstreetmap.org/wiki/France/OSM-FR/Groupes_de_travail#GT_International",
|
||||
"description": "",
|
||||
"category": "Général",
|
||||
"type": "working_group"
|
||||
},
|
||||
{
|
||||
"name": "GT Gestion et comptabilité",
|
||||
"url": "https://wiki.openstreetmap.org/wiki/France/OSM-FR/Groupes_de_travail#GT_Gestion_et_comptabilité",
|
||||
"description": "",
|
||||
"category": "Général",
|
||||
"type": "working_group"
|
||||
},
|
||||
{
|
||||
"name": "GT Soutiens",
|
||||
"url": "https://wiki.openstreetmap.org/wiki/France/OSM-FR/Groupes_de_travail#GT_Soutiens",
|
||||
"description": "",
|
||||
"category": "Général",
|
||||
"type": "working_group"
|
||||
},
|
||||
{
|
||||
"name": "GT Conférence SotM-FR",
|
||||
"url": "https://wiki.openstreetmap.org/wiki/France/OSM-FR/Groupes_de_travail#GT_Conférence_SotM-FR",
|
||||
"description": "",
|
||||
"category": "Général",
|
||||
"type": "working_group"
|
||||
},
|
||||
{
|
||||
"name": "Groupes spéciaux",
|
||||
"url": "https://wiki.openstreetmap.org/wiki/France/OSM-FR/Groupes_de_travail#Groupes_spéciaux",
|
||||
"description": "",
|
||||
"category": "Général",
|
||||
"type": "working_group"
|
||||
},
|
||||
{
|
||||
"name": "Groupes projets et thématiques",
|
||||
"url": "https://wiki.openstreetmap.org/wiki/France/OSM-FR/Groupes_de_travail#Groupes_projets_et_thématiques",
|
||||
"description": "",
|
||||
"category": "Général",
|
||||
"type": "working_group"
|
||||
}
|
||||
],
|
||||
"umap_url": "https://umap.openstreetmap.fr/fr/map/groupes-locaux-openstreetmap_152488"
|
||||
}
|
1269523
public/pages_unavailable_in_french.json
Normal file
1269523
public/pages_unavailable_in_french.json
Normal file
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
28
src/Twig/AppExtension.php
Normal file
28
src/Twig/AppExtension.php
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace App\Twig;
|
||||
|
||||
use Twig\Extension\AbstractExtension;
|
||||
use Twig\TwigFilter;
|
||||
|
||||
class AppExtension extends AbstractExtension
|
||||
{
|
||||
public function getFilters()
|
||||
{
|
||||
return [
|
||||
new TwigFilter('repeat', [$this, 'repeatFilter']),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Repeats a string a specified number of times
|
||||
*
|
||||
* @param string $string The string to repeat
|
||||
* @param int $times The number of times to repeat the string
|
||||
* @return string The repeated string
|
||||
*/
|
||||
public function repeatFilter($string, $times)
|
||||
{
|
||||
return str_repeat($string, $times);
|
||||
}
|
||||
}
|
|
@ -31,6 +31,16 @@
|
|||
<i class="bi bi-translate"></i> Pages sans traduction
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link {% if app.request.get('_route') == 'app_admin_wiki_pages_unavailable_in_french' %}active{% endif %}" href="{{ path('app_admin_wiki_pages_unavailable_in_french') }}">
|
||||
<i class="bi bi-globe"></i> Pages à traduire en français
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link {% if app.request.get('_route') == 'app_admin_wiki_osm_fr_groups' %}active{% endif %}" href="{{ path('app_admin_wiki_osm_fr_groups') }}">
|
||||
<i class="bi bi-people"></i> Groupes OSM-FR
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -3,20 +3,20 @@
|
|||
{% block title %}Pages Wiki OSM{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div class="container mt-4">
|
||||
{% include 'admin/_wiki_navigation.html.twig' %}
|
||||
|
||||
<h1>Pages Wiki OpenStreetMap</h1>
|
||||
<p class="lead">Comparaison des pages wiki en français et en anglais pour les clés OSM les plus utilisées.</p>
|
||||
<div class="container mt-4">
|
||||
{% include 'admin/_wiki_navigation.html.twig' %}
|
||||
|
||||
<div class="card mb-4">
|
||||
<div class="card-header">
|
||||
<h2>Liste des pages wiki</h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-hover">
|
||||
<thead class="thead-dark">
|
||||
<h1>Pages Wiki OpenStreetMap</h1>
|
||||
<p class="lead">Comparaison des pages wiki en français et en anglais pour les clés OSM les plus utilisées.</p>
|
||||
|
||||
<div class="card mb-4">
|
||||
<div class="card-header">
|
||||
<h2>Liste des pages wiki</h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-hover">
|
||||
<thead class="thead-dark">
|
||||
<tr>
|
||||
<th rowspan="2">Clé</th>
|
||||
<th colspan="4" class="text-center">Différences FR vs EN</th>
|
||||
|
@ -29,17 +29,17 @@
|
|||
<th class="text-center">Liens</th>
|
||||
<th class="text-center">Images</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for key, languages in wiki_pages %}
|
||||
{% if languages['en'] is defined and languages['fr'] is defined %}
|
||||
<tr>
|
||||
<td>
|
||||
<strong>{{ key }}</strong>
|
||||
</td>
|
||||
|
||||
|
||||
{% set diff = page_differences[key] %}
|
||||
|
||||
|
||||
<td class="text-center">
|
||||
{% if diff.section_diff > 0 %}
|
||||
<span class="badge bg-success">{{ diff.section_diff_formatted }}</span>
|
||||
|
@ -49,7 +49,7 @@
|
|||
<span class="badge bg-secondary">0</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
|
||||
|
||||
<td class="text-center">
|
||||
{% if diff.word_diff > 0 %}
|
||||
<span class="badge bg-success">{{ diff.word_diff_formatted }}</span>
|
||||
|
@ -59,7 +59,7 @@
|
|||
<span class="badge bg-secondary">0</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
|
||||
|
||||
<td class="text-center">
|
||||
{% if diff.link_diff > 0 %}
|
||||
<span class="badge bg-success">{{ diff.link_diff_formatted }}</span>
|
||||
|
@ -69,7 +69,7 @@
|
|||
<span class="badge bg-secondary">0</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
|
||||
|
||||
<td class="text-center">
|
||||
{% if diff.media_diff > 0 %}
|
||||
<span class="badge bg-success">{{ diff.media_diff_formatted }}</span>
|
||||
|
@ -79,7 +79,7 @@
|
|||
<span class="badge bg-secondary">0</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
|
||||
|
||||
<td class="text-center">
|
||||
{% set score = languages['en'].staleness_score|default(0) %}
|
||||
{% if score > 50 %}
|
||||
|
@ -92,13 +92,16 @@
|
|||
</td>
|
||||
<td class="text-center">
|
||||
<div class="btn-group" role="group">
|
||||
<a href="{{ languages['en'].url }}" target="_blank" class="btn btn-sm btn-outline-primary" title="Version anglaise">
|
||||
<a href="{{ languages['en'].url }}" target="_blank"
|
||||
class="btn btn-sm btn-outline-primary" title="Version anglaise">
|
||||
<i class="bi bi-translate"></i> EN
|
||||
</a>
|
||||
<a href="{{ languages['fr'].url }}" target="_blank" class="btn btn-sm btn-outline-info" title="Version française">
|
||||
<a href="{{ languages['fr'].url }}" target="_blank"
|
||||
class="btn btn-sm btn-outline-info" title="Version française">
|
||||
<i class="bi bi-translate"></i> FR
|
||||
</a>
|
||||
<a href="{{ path('app_admin_wiki_compare', {'key': key}) }}" class="btn btn-sm btn-outline-secondary" title="Comparer les versions">
|
||||
<a href="{{ path('app_admin_wiki_compare', {'key': key}) }}"
|
||||
class="btn btn-sm btn-outline-secondary" title="Comparer les versions">
|
||||
<i class="bi bi-arrows-angle-expand"></i> Comparer
|
||||
</a>
|
||||
</div>
|
||||
|
@ -106,65 +109,74 @@
|
|||
</tr>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if missing_translations|length > 0 %}
|
||||
<div class="card mb-4">
|
||||
<div class="card-header bg-warning text-dark">
|
||||
<h2>Pages manquantes en français</h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p>Ces pages wiki ont une version anglaise mais pas de traduction française.</p>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-hover">
|
||||
<thead class="thead-dark">
|
||||
<tr>
|
||||
<th>Clé</th>
|
||||
<th>Sections</th>
|
||||
<th>Mots</th>
|
||||
<th>Liens</th>
|
||||
<th>Score de décrépitude</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for key, page in missing_translations %}
|
||||
<tr>
|
||||
<td><strong>{{ key }}</strong></td>
|
||||
<td>{{ page.sections }}</td>
|
||||
<td>{{ page.word_count }}</td>
|
||||
<td>{{ page.link_count }}</td>
|
||||
<td>
|
||||
<span class="badge bg-danger">{{ page.staleness_score|default(100) }}</span>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<div class="btn-group" role="group">
|
||||
<a href="{{ page.url }}" target="_blank" class="btn btn-sm btn-outline-primary" title="Version anglaise">
|
||||
<i class="bi bi-translate"></i> EN
|
||||
</a>
|
||||
<a href="{{ path('app_admin_wiki_compare', {'key': key}) }}" class="btn btn-sm btn-outline-secondary" title="Voir les détails et créer la page française">
|
||||
<i class="bi bi-arrows-angle-expand"></i> Comparer
|
||||
</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<p>
|
||||
le score de fraîcheur prend en compte d'avantage la différence entre le nombre de mots que l'ancienneté de modification.
|
||||
On compte aussi le nombre de sections et de liens.
|
||||
</p>
|
||||
<div class="mt-3">
|
||||
|
||||
{% if missing_translations|length > 0 %}
|
||||
<div class="card mb-4">
|
||||
<div class="card-header bg-warning text-dark">
|
||||
<h2>Pages manquantes en français</h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p>Ces pages wiki ont une version anglaise mais pas de traduction française.</p>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-hover">
|
||||
<thead class="thead-dark">
|
||||
<tr>
|
||||
<th>Clé</th>
|
||||
<th>Sections</th>
|
||||
<th>Mots</th>
|
||||
<th>Liens</th>
|
||||
<th>Score de décrépitude</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for key, page in missing_translations %}
|
||||
<tr>
|
||||
<td><strong>{{ key }}</strong></td>
|
||||
<td>{{ page.sections }}</td>
|
||||
<td>{{ page.word_count }}</td>
|
||||
<td>{{ page.link_count }}</td>
|
||||
<td>
|
||||
<span class="badge bg-danger">{{ page.staleness_score|default(100) }}</span>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<div class="btn-group" role="group">
|
||||
<a href="{{ page.url }}" target="_blank"
|
||||
class="btn btn-sm btn-outline-info" title="Version anglaise">
|
||||
<i class="bi bi-flag-fill"></i> EN
|
||||
</a>
|
||||
<a href="https://wiki.openstreetmap.org/w/index.php?title=FR:{{ key }}&action=edit"
|
||||
target="_blank"
|
||||
class="btn btn-sm btn-outline-primary" title="Version anglaise">
|
||||
<i class="bi bi-translate"></i> créer FR
|
||||
</a>
|
||||
{# <a href="{{ path('app_admin_wiki_compare', {'key': key}) }}" #}
|
||||
{# class="btn btn-sm btn-outline-secondary" #}
|
||||
{# title="Voir les détails et créer la page française"> #}
|
||||
{# <i class="bi bi-arrows-angle-expand"></i> Comparer #}
|
||||
{# </a> #}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<p>
|
||||
le score de fraîcheur prend en compte d'avantage la différence entre le nombre de mots que l'ancienneté de
|
||||
modification.
|
||||
On compte aussi le nombre de sections et de liens.
|
||||
</p>
|
||||
<div class="mt-3">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
File diff suppressed because it is too large
Load diff
|
@ -9,38 +9,38 @@
|
|||
<h1>Pages Wiki françaises sans traduction anglaise</h1>
|
||||
<p class="lead">Liste des pages françaises du wiki OSM qui n'ont pas de traduction en anglais.</p>
|
||||
|
||||
{% if last_updated %}
|
||||
<div class="alert alert-info">
|
||||
<i class="bi bi-info-circle"></i> Dernière mise à jour : {{ last_updated|date('d/m/Y H:i') }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="card mb-4">
|
||||
<div class="card-header">
|
||||
<h2>Pages françaises uniquement</h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% if french_only_pages|length > 0 %}
|
||||
{% if untranslated_pages|length > 0 %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-hover">
|
||||
<thead class="thead-dark">
|
||||
<tr>
|
||||
<th>Titre</th>
|
||||
<th>Clé</th>
|
||||
<th>Sections</th>
|
||||
<th>Mots</th>
|
||||
<th>Liens</th>
|
||||
<th>Dernière modification</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for key, page in french_only_pages %}
|
||||
{% for page in untranslated_pages %}
|
||||
<tr>
|
||||
<td><strong>{{ key }}</strong></td>
|
||||
<td>{{ page.sections }}</td>
|
||||
<td>{{ page.word_count }}</td>
|
||||
<td>{{ page.link_count }}</td>
|
||||
<td>{{ page.last_modified }}</td>
|
||||
<td><strong>{{ page.title }}</strong></td>
|
||||
<td>{{ page.key }}</td>
|
||||
<td>
|
||||
<div class="btn-group" role="group">
|
||||
<a href="{{ page.url }}" target="_blank" class="btn btn-sm btn-outline-info" title="Version française">
|
||||
<i class="bi bi-translate"></i> FR
|
||||
</a>
|
||||
<a href="https://wiki.openstreetmap.org/wiki/Key:{{ key }}" target="_blank" class="btn btn-sm btn-success" title="Créer la version anglaise">
|
||||
<a href="https://wiki.openstreetmap.org/wiki/{{ page.key }}" target="_blank" class="btn btn-sm btn-success" title="Créer la version anglaise">
|
||||
<i class="bi bi-plus-circle"></i> Créer EN
|
||||
</a>
|
||||
</div>
|
||||
|
|
161
templates/admin/wiki_osm_fr_groups.html.twig
Normal file
161
templates/admin/wiki_osm_fr_groups.html.twig
Normal file
|
@ -0,0 +1,161 @@
|
|||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}Groupes OSM-FR{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div class="container mt-4">
|
||||
{% include 'admin/_wiki_navigation.html.twig' %}
|
||||
|
||||
<h1>Groupes OSM-FR</h1>
|
||||
<p class="lead">Liste des groupes de travail et des groupes locaux d'OpenStreetMap France.</p>
|
||||
|
||||
{% if last_updated %}
|
||||
<div class="alert alert-info">
|
||||
<i class="bi bi-info-circle"></i> Dernière mise à jour : {{ last_updated|date('d/m/Y H:i') }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- Carte uMap des groupes locaux -->
|
||||
<div class="card mb-4">
|
||||
<div class="card-header bg-primary text-white">
|
||||
<h2>
|
||||
<a href="{{ umap_url }}">
|
||||
|
||||
Carte des groupes locaux
|
||||
</a>
|
||||
</h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="ratio ratio-16x9">
|
||||
<iframe src="{{ umap_url }}" frameborder="0"></iframe>
|
||||
</div>
|
||||
<div class="mt-3">
|
||||
<a href="{{ umap_url }}" target="_blank" class="btn btn-outline-primary">
|
||||
<i class="bi bi-box-arrow-up-right"></i> Voir la carte en plein écran
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Groupes de travail -->
|
||||
<div class="card mb-4">
|
||||
<div class="card-header bg-success text-white">
|
||||
<h2>Groupes de travail</h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% if working_groups|length > 0 %}
|
||||
<div class="accordion" id="workingGroupsAccordion">
|
||||
{% for category, groups in working_groups %}
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header" id="heading{{ loop.index }}">
|
||||
<button class="accordion-button {% if not loop.first %}collapsed{% endif %}"
|
||||
type="button" data-bs-toggle="collapse"
|
||||
data-bs-target="#collapse{{ loop.index }}"
|
||||
aria-expanded="{{ loop.first ? 'true' : 'false' }}"
|
||||
aria-controls="collapse{{ loop.index }}">
|
||||
{{ category }} ({{ groups|length }})
|
||||
</button>
|
||||
</h2>
|
||||
<div id="collapse{{ loop.index }}"
|
||||
class="accordion-collapse collapse {% if loop.first %}show{% endif %}"
|
||||
aria-labelledby="heading{{ loop.index }}" data-bs-parent="#workingGroupsAccordion">
|
||||
<div class="accordion-body">
|
||||
<div class="list-group">
|
||||
{% for group in groups %}
|
||||
<a href="{{ group.url }}" target="_blank"
|
||||
class="list-group-item list-group-item-action">
|
||||
<div class="d-flex w-100 justify-content-between">
|
||||
<h5 class="mb-1">{{ group.name }}</h5>
|
||||
</div>
|
||||
{% if group.description %}
|
||||
<p class="mb-1">{{ group.description }}</p>
|
||||
{% endif %}
|
||||
<small class="text-muted">
|
||||
<i class="bi bi-box-arrow-up-right"></i> Voir sur le wiki
|
||||
</small>
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="alert alert-info">
|
||||
<p><i class="bi bi-info-circle"></i> Aucun groupe de travail n'a été trouvé.</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Groupes locaux -->
|
||||
<div class="card mb-4">
|
||||
<div class="card-header bg-info text-white">
|
||||
<h2>Groupes locaux</h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% if local_groups|length > 0 %}
|
||||
<div class="row row-cols-1 row-cols-md-2 row-cols-lg-3 g-4">
|
||||
{% for group in local_groups %}
|
||||
<div class="col">
|
||||
<div class="card h-100">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">{{ group.name }}</h5>
|
||||
{% if group.description %}
|
||||
<p class="card-text">{{ group.description }}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<a href="{{ group.url }}" target="_blank"
|
||||
class="btn btn-sm btn-outline-primary">
|
||||
<i class="bi bi-box-arrow-up-right"></i> Voir sur le wiki
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="alert alert-info">
|
||||
<p><i class="bi bi-info-circle"></i> Aucun groupe local n'a été trouvé.</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card mb-4">
|
||||
<div class="card-header">
|
||||
<h2>À propos des groupes OSM-FR</h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<h5>Groupes de travail</h5>
|
||||
<p>Les groupes de travail sont des équipes thématiques qui se concentrent sur des aspects spécifiques
|
||||
d'OpenStreetMap en France. Ils permettent de coordonner les efforts sur des sujets particuliers
|
||||
comme l'import de données, la cartographie des transports, etc.</p>
|
||||
|
||||
<h5>Groupes locaux</h5>
|
||||
<p>Les groupes locaux sont des communautés géographiques de contributeurs OpenStreetMap. Ils organisent
|
||||
des rencontres, des ateliers de cartographie et d'autres événements pour promouvoir OSM dans leur
|
||||
région.</p>
|
||||
|
||||
<div class="d-grid gap-2 col-md-6 mx-auto mt-3">
|
||||
<a href="https://wiki.openstreetmap.org/wiki/France/OSM-FR/Groupes_de_travail" target="_blank"
|
||||
class="btn btn-outline-success">
|
||||
<i class="bi bi-box-arrow-up-right"></i> Voir tous les groupes de travail sur le wiki
|
||||
</a>
|
||||
<a href="https://wiki.openstreetmap.org/wiki/France/OSM-FR#Groupes_locaux" target="_blank"
|
||||
class="btn btn-outline-info">
|
||||
<i class="bi bi-box-arrow-up-right"></i> Voir tous les groupes locaux sur le wiki
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-3">
|
||||
<a href="{{ path('app_admin_wiki') }}" class="btn btn-secondary">
|
||||
<i class="bi bi-arrow-left"></i> Retour à la liste des pages wiki
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
130
templates/admin/wiki_pages_unavailable_in_french.html.twig
Normal file
130
templates/admin/wiki_pages_unavailable_in_french.html.twig
Normal file
|
@ -0,0 +1,130 @@
|
|||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}Pages Wiki non disponibles en français{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div class="container mt-4">
|
||||
{% include 'admin/_wiki_navigation.html.twig' %}
|
||||
|
||||
<h1>Pages Wiki non disponibles en français</h1>
|
||||
<p class="lead">Liste des pages du wiki OSM qui n'ont pas de traduction française, groupées par langue d'origine.</p>
|
||||
|
||||
{% if last_updated %}
|
||||
<div class="alert alert-info">
|
||||
<i class="bi bi-info-circle"></i> Dernière mise à jour : {{ last_updated|date('d/m/Y H:i') }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="card mb-4">
|
||||
<div class="card-header">
|
||||
<h2>Statistiques</h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="card text-white bg-primary mb-3">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Total des pages</h5>
|
||||
<p class="card-text display-4">{{ all_pages|length }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="card text-white bg-success mb-3">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Pages en anglais</h5>
|
||||
<p class="card-text display-4">{{ grouped_pages['En']|default([])|length }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="card text-white bg-info mb-3">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Langues différentes</h5>
|
||||
<p class="card-text display-4">{{ grouped_pages|length }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Pages groupées par langue -->
|
||||
<div class="accordion" id="languageAccordion">
|
||||
{% for lang_prefix, pages in grouped_pages %}
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header" id="heading{{ lang_prefix }}">
|
||||
<button class="accordion-button {% if lang_prefix != 'En' %}collapsed{% endif %}" type="button" data-bs-toggle="collapse" data-bs-target="#collapse{{ lang_prefix }}" aria-expanded="{{ lang_prefix == 'En' ? 'true' : 'false' }}" aria-controls="collapse{{ lang_prefix }}">
|
||||
{% if lang_prefix == 'En' %}
|
||||
<strong class="text-success">Pages en anglais ({{ pages|length }})</strong>
|
||||
{% elseif lang_prefix == 'Other' %}
|
||||
<strong>Autres pages ({{ pages|length }})</strong>
|
||||
{% else %}
|
||||
<strong>Pages en {{ lang_prefix }} ({{ pages|length }})</strong>
|
||||
{% endif %}
|
||||
</button>
|
||||
</h2>
|
||||
<div id="collapse{{ lang_prefix }}" class="accordion-collapse collapse {% if lang_prefix == 'En' %}show{% endif %}" aria-labelledby="heading{{ lang_prefix }}" data-bs-parent="#languageAccordion">
|
||||
<div class="accordion-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-hover">
|
||||
<thead class="thead-dark">
|
||||
<tr>
|
||||
<th>Titre</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for page in pages %}
|
||||
<tr>
|
||||
<td>
|
||||
<strong>{{ page.title }}</strong>
|
||||
{% if page.is_english %}
|
||||
<span class="badge bg-success">Priorité</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
<div class="btn-group" role="group">
|
||||
<a href="{{ page.url }}" target="_blank" class="btn btn-sm btn-outline-primary" title="Voir la page originale">
|
||||
<i class="bi bi-eye"></i> Voir
|
||||
</a>
|
||||
{% set fr_url = page.url|replace({'/wiki/': '/wiki/FR:'}) %}
|
||||
<a href="{{ fr_url }}" target="_blank" class="btn btn-sm btn-success" title="Créer la traduction française">
|
||||
<i class="bi bi-plus-circle"></i> Traduire
|
||||
</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<div class="card mt-4 mb-4">
|
||||
<div class="card-header">
|
||||
<h2>À propos des pages non disponibles en français</h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p>Ces pages sont des contenus du wiki OpenStreetMap qui n'ont pas encore été traduits en français.</p>
|
||||
<p>Contribuer à la traduction de ces pages permet de :</p>
|
||||
<ul>
|
||||
<li>Rendre la documentation OSM plus accessible aux contributeurs francophones</li>
|
||||
<li>Améliorer la qualité des contributions en français</li>
|
||||
<li>Faciliter l'apprentissage et l'utilisation d'OpenStreetMap pour les nouveaux utilisateurs</li>
|
||||
</ul>
|
||||
<p><strong>Priorité aux pages anglaises :</strong> Les pages commençant par "En:" sont prioritaires car l'anglais est la langue principale du wiki OSM.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-3">
|
||||
<a href="{{ path('app_admin_wiki') }}" class="btn btn-secondary">
|
||||
<i class="bi bi-arrow-left"></i> Retour à la liste des pages wiki
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -3,92 +3,119 @@
|
|||
{% block title %}Pages Wiki avec suppressions suspectes{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div class="container mt-4">
|
||||
{% include 'admin/_wiki_navigation.html.twig' %}
|
||||
|
||||
<h1>Pages Wiki avec suppressions suspectes</h1>
|
||||
<p class="lead">Pages françaises du wiki OSM qui ont des suppressions suspectes, avec un grand pourcentage de suppression par rapport à la version anglaise.</p>
|
||||
<div class="container mt-4">
|
||||
{% include 'admin/_wiki_navigation.html.twig' %}
|
||||
|
||||
<div class="card mb-4">
|
||||
<div class="card-header">
|
||||
<h2>Pages avec suppressions suspectes</h2>
|
||||
<h1>Pages Wiki avec suppressions suspectes</h1>
|
||||
|
||||
<div class="alert alert-info">
|
||||
<i class="bi bi-info-circle"></i>
|
||||
Cette page présente deux types de suppressions suspectes :
|
||||
<ul>
|
||||
<li><strong>Suppressions récentes</strong> : Détectées en temps réel dans les changements récents du
|
||||
wiki (suppressions > 20 caractères)
|
||||
</li>
|
||||
<li><strong>Différences de contenu</strong> : Pages françaises contenant significativement moins de mots
|
||||
que leurs équivalents anglais
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% if suspicious_pages|length > 0 %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-hover">
|
||||
<thead class="thead-dark">
|
||||
|
||||
<!-- Suppressions récentes -->
|
||||
<div class="card mb-4">
|
||||
<div class="card-header bg-danger text-white">
|
||||
<h2>Suppressions récentes suspectes</h2>
|
||||
{% if last_updated %}
|
||||
<small>Dernière mise à jour : {{ last_updated|date('d/m/Y H:i') }}</small>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% if recent_deletions is defined and recent_deletions|length > 0 %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-hover">
|
||||
<thead class="thead-dark">
|
||||
<tr>
|
||||
<th>Clé</th>
|
||||
<th>Mots (EN)</th>
|
||||
<th>Mots (FR)</th>
|
||||
<th>Différence</th>
|
||||
<th>% Suppression</th>
|
||||
<th>Page</th>
|
||||
<th>Suppression</th>
|
||||
<th>Date</th>
|
||||
<th>Utilisateur</th>
|
||||
<th>Commentaire</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for page in suspicious_pages %}
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for deletion in recent_deletions %}
|
||||
<tr>
|
||||
<td><strong>{{ page.key }}</strong></td>
|
||||
<td>{{ page.en_page.word_count }}</td>
|
||||
<td>{{ page.fr_page.word_count }}</td>
|
||||
<td>{{ page.en_page.word_count - page.fr_page.word_count }}</td>
|
||||
<td><strong>{{ deletion.page_title }}</strong></td>
|
||||
<td>
|
||||
{% if page.deletion_percentage > 70 %}
|
||||
<span class="badge bg-danger">{{ page.deletion_percentage }}%</span>
|
||||
{% elseif page.deletion_percentage > 50 %}
|
||||
<span class="badge bg-warning text-dark">{{ page.deletion_percentage }}%</span>
|
||||
{% else %}
|
||||
<span class="badge bg-info">{{ page.deletion_percentage }}%</span>
|
||||
{% endif %}
|
||||
<span class="badge bg-danger">{{ deletion.deletion_size }} caractères</span>
|
||||
</td>
|
||||
<td>{{ deletion.timestamp }}</td>
|
||||
<td>{{ deletion.user }}</td>
|
||||
<td>{{ deletion.comment }}</td>
|
||||
<td>
|
||||
<div class="btn-group" role="group">
|
||||
<a href="{{ page.en_page.url }}" target="_blank" class="btn btn-sm btn-outline-primary" title="Version anglaise">
|
||||
<i class="bi bi-translate"></i> EN
|
||||
<a href="{{ deletion.page_url }}" target="_blank"
|
||||
class="btn btn-sm btn-outline-primary" title="Voir la page">
|
||||
<i class="bi bi-eye"></i> Voir
|
||||
</a>
|
||||
<a href="{{ page.fr_page.url }}" target="_blank" class="btn btn-sm btn-outline-info" title="Version française">
|
||||
<i class="bi bi-translate"></i> FR
|
||||
</a>
|
||||
<a href="{{ path('app_admin_wiki_compare', {'key': page.key}) }}" class="btn btn-sm btn-outline-secondary" title="Comparer les versions">
|
||||
<i class="bi bi-arrows-angle-expand"></i> Comparer
|
||||
<a href="https://wiki.openstreetmap.org/w/index.php?title={{ deletion.page_title|url_encode }}&action=history"
|
||||
target="_blank" class="btn btn-sm btn-outline-secondary"
|
||||
title="Historique">
|
||||
<i class="bi bi-clock-history"></i> Historique
|
||||
</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="alert alert-info">
|
||||
<p><i class="bi bi-info-circle"></i> Aucune page avec suppressions suspectes n'a été trouvée.</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="mt-3">
|
||||
<a href="https://wiki.openstreetmap.org/w/index.php?hidebots=1&hidenewpages=1&hidecategorization=1&hideWikibase=1&hidelog=1&hidenewuserlog=1&namespace=202&limit=250&days=30&enhanced=1&title=Special:RecentChanges&urlversion=2"
|
||||
target="_blank" class="btn btn-outline-primary">
|
||||
<i class="bi bi-arrow-right-circle"></i> Voir tous les changements récents sur le wiki
|
||||
</a>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="alert alert-info">
|
||||
<p><i class="bi bi-info-circle"></i> Aucune suppression suspecte récente n'a été détectée.</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card mb-4">
|
||||
<div class="card-header">
|
||||
<h2>À propos des suppressions suspectes</h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p>Les suppressions suspectes sont identifiées lorsque la version française d'une page wiki contient significativement moins de mots que la version anglaise (plus de 30% de différence).</p>
|
||||
<p>Cela peut indiquer :</p>
|
||||
<ul>
|
||||
<li>Une traduction incomplète</li>
|
||||
<li>Des sections manquantes dans la version française</li>
|
||||
<li>Des mises à jour importantes dans la version anglaise qui n'ont pas été reportées en français</li>
|
||||
</ul>
|
||||
<p>Ces pages sont des candidates prioritaires pour une mise à jour de la traduction française.</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Différences de contenu -->
|
||||
|
||||
<div class="mt-3">
|
||||
<a href="{{ path('app_admin_wiki') }}" class="btn btn-secondary">
|
||||
<i class="bi bi-arrow-left"></i> Retour à la liste des pages wiki
|
||||
</a>
|
||||
|
||||
<div class="card mb-4">
|
||||
<div class="card-header">
|
||||
<h2>À propos des suppressions suspectes</h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<h5>Suppressions récentes</h5>
|
||||
<p>Les suppressions récentes sont détectées en analysant les changements récents du wiki OSM. Toute
|
||||
suppression de plus de 20 caractères est considérée comme potentiellement suspecte et mérite une
|
||||
vérification.</p>
|
||||
|
||||
<h5>Différences de contenu</h5>
|
||||
<p>Les différences de contenu sont identifiées lorsque la version française d'une page wiki contient
|
||||
significativement moins de mots que la version anglaise (plus de 30% de différence).</p>
|
||||
<p>Cela peut indiquer :</p>
|
||||
<ul>
|
||||
<li>Une traduction incomplète</li>
|
||||
<li>Des sections manquantes dans la version française</li>
|
||||
<li>Des mises à jour importantes dans la version anglaise qui n'ont pas été reportées en français
|
||||
</li>
|
||||
</ul>
|
||||
<p>Ces pages sont des candidates prioritaires pour une mise à jour de la traduction française.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-3">
|
||||
<a href="{{ path('app_admin_wiki') }}" class="btn btn-secondary">
|
||||
<i class="bi bi-arrow-left"></i> Retour à la liste des pages wiki
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -6,42 +6,40 @@
|
|||
<div class="container mt-4">
|
||||
{% include 'admin/_wiki_navigation.html.twig' %}
|
||||
|
||||
<h1>Propositions de tags OSM en cours de vote</h1>
|
||||
<p class="lead">Liste des propositions de tags OpenStreetMap actuellement en cours de vote ou de discussion.</p>
|
||||
<h1>Propositions de tags OSM</h1>
|
||||
<p class="lead">Liste des propositions de tags OpenStreetMap actuellement en cours de vote ou récemment modifiées.</p>
|
||||
|
||||
{% if last_updated %}
|
||||
<div class="alert alert-info">
|
||||
<i class="bi bi-info-circle"></i> Dernière mise à jour : {{ last_updated|date('d/m/Y H:i') }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- Propositions en cours de vote -->
|
||||
<div class="card mb-4">
|
||||
<div class="card-header">
|
||||
<h2>Propositions actives</h2>
|
||||
<div class="card-header bg-primary text-white">
|
||||
<h2>Propositions en cours de vote</h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% if proposals|length > 0 %}
|
||||
{% set voting_proposals = proposals|filter(p => p.type == 'voting') %}
|
||||
{% if voting_proposals|length > 0 %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-hover">
|
||||
<thead class="thead-dark">
|
||||
<tr>
|
||||
<th>Fonctionnalité</th>
|
||||
<th>Proposition</th>
|
||||
<th>Description</th>
|
||||
<th>Proposé par</th>
|
||||
<th>Statut</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for proposal in proposals %}
|
||||
{% for proposal in voting_proposals %}
|
||||
<tr>
|
||||
<td>{{ proposal.feature }}</td>
|
||||
<td><strong>{{ proposal.feature }}</strong></td>
|
||||
<td>{{ proposal.description }}</td>
|
||||
<td>{{ proposal.proposer }}</td>
|
||||
<td>
|
||||
{% if 'voting' in proposal.status|lower %}
|
||||
<span class="badge bg-primary">En vote</span>
|
||||
{% elseif 'draft' in proposal.status|lower %}
|
||||
<span class="badge bg-warning text-dark">Brouillon</span>
|
||||
{% elseif 'rfc' in proposal.status|lower %}
|
||||
<span class="badge bg-info">RFC</span>
|
||||
{% else %}
|
||||
<span class="badge bg-secondary">{{ proposal.status }}</span>
|
||||
{% endif %}
|
||||
<span class="badge bg-primary">En vote</span>
|
||||
</td>
|
||||
<td>
|
||||
<a href="{{ proposal.url }}" target="_blank" class="btn btn-sm btn-outline-primary">
|
||||
|
@ -55,7 +53,49 @@
|
|||
</div>
|
||||
{% else %}
|
||||
<div class="alert alert-info">
|
||||
<p><i class="bi bi-info-circle"></i> Aucune proposition de tag n'a été trouvée.</p>
|
||||
<p><i class="bi bi-info-circle"></i> Aucune proposition en cours de vote n'a été trouvée.</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Propositions récemment modifiées -->
|
||||
<div class="card mb-4">
|
||||
<div class="card-header bg-info text-white">
|
||||
<h2>Propositions récemment modifiées</h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% set recent_proposals = proposals|filter(p => p.type == 'recent') %}
|
||||
{% if recent_proposals|length > 0 %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-hover">
|
||||
<thead class="thead-dark">
|
||||
<tr>
|
||||
<th>Proposition</th>
|
||||
<th>Dernière modification</th>
|
||||
<th>Modifié par</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for proposal in recent_proposals %}
|
||||
<tr>
|
||||
<td><strong>{{ proposal.feature }}</strong></td>
|
||||
<td>{{ proposal.description }}</td>
|
||||
<td>{{ proposal.proposer }}</td>
|
||||
<td>
|
||||
<a href="{{ proposal.url }}" target="_blank" class="btn btn-sm btn-outline-primary">
|
||||
<i class="bi bi-box-arrow-up-right"></i> Voir
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="alert alert-info">
|
||||
<p><i class="bi bi-info-circle"></i> Aucune proposition récemment modifiée n'a été trouvée.</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue