369 lines
22 KiB
HTML
369 lines
22 KiB
HTML
{% extends "base.html" %}
|
|
{% load static %}
|
|
{% load tz %}
|
|
{% load i18n %}
|
|
|
|
{% block content %}
|
|
<div class="row mt-2" style="height: calc(100vh - 200px);">
|
|
<div class="col-md-8" style="max-height: calc(100vh - 200px); overflow: auto;">
|
|
<h3 class="h3">
|
|
<i class="bi bi-signpost-2"></i><span class="mx-2">{{ street.code }}</span> - <span class="mx-2">{{ street.get_name }}</span>
|
|
</h3>
|
|
<hr>
|
|
<div class="row mb-4">
|
|
<div class="col-md-6">
|
|
<label class="me-2 mb-2">{% translate "Commune:" %}</label>{{ street.municipality }}<br>
|
|
{% if street.road_code %}
|
|
<label class="me-2 mb-2">{% translate "Code voirie:" %}</label>{{ street.road_code }}<br>
|
|
{% endif %}
|
|
{% if street.section_code %}
|
|
<label class="me-2 mb-2">{% translate "Section:" %}</label>{{ street.section_code }}<br>
|
|
{% endif %}
|
|
{% if street.street_level %}
|
|
<label class="me-2 mb-2">{% translate "Niveau:" %}</label>{{ street.street_level }}<br>
|
|
{% endif %}
|
|
{% if street.lon %}
|
|
<a href="https://www.google.com/maps?cbll={{ street.lat|floatformat:'6u'}},{{ street.lon|floatformat:'6u'}}&cbp=12,0,0,0,5&layer=c&panoid=" target="_blank" style="text-decoration: none; font-size: 16px; display: flex; align-items: center;">
|
|
<img src="{% static 'common/google-street-view-logo.png' %}" alt="{% translate 'Street View' %}" height="20" style="margin-right: 8px;">
|
|
{% translate "View in Google Street View" %}
|
|
</a>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Documents -->
|
|
<div class="card mb-4">
|
|
<div class="card-header d-flex justify-content-between align-items-center">
|
|
<h4>{% translate "Documents" %}</h4>
|
|
<button onclick="" class="btn btn-light border-0" title="{% translate 'Ajouter' %}" data-bs-toggle="modal" data-bs-target="#addDocumentModal">
|
|
<i class="bi bi-plus-circle text-primary"></i>
|
|
</button>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="row">
|
|
{% for document in main_documents %}
|
|
{% if document %}
|
|
<div class="col-md-3 mb-3">
|
|
<div class="card h-100 shadow-sm border rounded-3">
|
|
<div class="d-flex">
|
|
<!-- Colonne gauche : contenu document -->
|
|
<div class="flex-grow-1 p-2">
|
|
<div class="d-flex flex-column align-items-center mb-2">
|
|
<!-- Badge centré -->
|
|
<div class="text-muted" style="font-size: 0.85em;">
|
|
<span class="badge bg-primary">{{ document.document_type }}</span>
|
|
</div>
|
|
|
|
<!-- Image -->
|
|
<a href="{{ document.file.url }}" target="_blank" class="text-decoration-none w-100">
|
|
<div class="img-thumbnail d-flex justify-content-center align-items-center mt-1" style="width: 100%; height: 100px; overflow: hidden; background-color: #f8f9fa;">
|
|
{% if document.thumbnail %}
|
|
<img src="{{ document.thumbnail.url }}" alt="{{ document.file.name }}" style="max-height: 100%; max-width: 100%; object-fit: contain;">
|
|
{% else %}
|
|
<img src="{{ document.file.url }}" alt="{{ document.file.name }}" style="max-height: 100%; max-width: 100%; object-fit: contain;">
|
|
{% endif %}
|
|
</div>
|
|
</a>
|
|
</div>
|
|
|
|
<div class="text-muted text-start" style="font-size: 0.85em;">
|
|
{{ document.upload_date|timezone:"Europe/Paris"|date:"d/m/Y" }}<br>
|
|
{{ document.uploaded_by.username }}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Colonne droite : icônes -->
|
|
<div class="d-flex flex-column justify-content-end align-items-center p-2" style="width: 40px; min-height: 100%;">
|
|
<!-- Historique -->
|
|
<button class="btn btn-sm p-0 border-0 bg-transparent mb-2"
|
|
data-bs-toggle="modal"
|
|
data-bs-target="#documentHistoryModal"
|
|
data-document-type="{{ document.document_type }}"
|
|
data-street-id="{{ document.street.id }}"
|
|
title="{% translate 'Historique' %}">
|
|
<i class="bi bi-clock-history text-primary"></i>
|
|
</button>
|
|
<!-- Supprimer -->
|
|
<button class="btn btn-sm p-0 border-0 bg-transparent mb-2"
|
|
data-bs-toggle="modal"
|
|
data-bs-target="#documentDeleteModal"
|
|
data-filename="{{ document.filename }}"
|
|
data-delete-url="{% url 'assets:roads_streets_delete_document' document.id %}"
|
|
title="{% translate 'Supprimer' %}">
|
|
<i class="bi bi-trash text-danger"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
{% endfor %}
|
|
</div>
|
|
<div class="row">
|
|
{% for document in other_documents %}
|
|
{% if document %}
|
|
<div class="col-md-3 mb-3">
|
|
<div class="card h-100 shadow-sm border rounded-3">
|
|
<div class="d-flex">
|
|
<!-- Colonne gauche : contenu document -->
|
|
<div class="flex-grow-1 p-2">
|
|
<div class="d-flex flex-column align-items-center mb-2">
|
|
<!-- Badge centré -->
|
|
<div class="text-muted" style="font-size: 0.85em;">
|
|
<span class="badge bg-secondary">{{ document.document_type }}</span>
|
|
</div>
|
|
|
|
<!-- Image -->
|
|
<a href="{{ document.file.url }}" target="_blank" class="text-decoration-none w-100">
|
|
<div class="img-thumbnail d-flex justify-content-center align-items-center mt-1" style="width: 100%; height: 100px; overflow: hidden; background-color: #f8f9fa;">
|
|
{% if document.thumbnail %}
|
|
<img src="{{ document.thumbnail.url }}" alt="{{ document.file.name }}" style="max-height: 100%; max-width: 100%; object-fit: contain;">
|
|
{% else %}
|
|
<img src="{{ document.file.url }}" alt="{{ document.file.name }}" style="max-height: 100%; max-width: 100%; object-fit: contain;">
|
|
{% endif %}
|
|
</div>
|
|
</a>
|
|
</div>
|
|
|
|
<div class="text-muted text-start" style="font-size: 0.85em;">
|
|
{{ document.upload_date|timezone:"Europe/Paris"|date:"d/m/Y" }}<br>
|
|
{{ document.uploaded_by.username }}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Colonne droite : icônes -->
|
|
<div class="d-flex flex-column justify-content-end align-items-center p-2" style="width: 40px; min-height: 100%;">
|
|
<!-- Supprimer -->
|
|
<button class="btn btn-sm p-0 border-0 bg-transparent mb-2"
|
|
data-bs-toggle="modal"
|
|
data-bs-target="#documentDeleteModal"
|
|
data-filename="{{ document.filename }}"
|
|
data-delete-url="{% url 'assets:roads_streets_delete_document' document.id %}"
|
|
title="{% translate 'Supprimer' %}">
|
|
<i class="bi bi-trash text-danger"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- Modal form add document -->
|
|
<div class="modal fade" id="addDocumentModal" tabindex="-1" aria-labelledby="addDocumentModalLabel" aria-hidden="true" style="z-index: 10050;">
|
|
<div class="modal-dialog modal-lg">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="addDocumentModalLabel">{% translate "Ajouter des documents" %}</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="{% translate 'Fermer' %}"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<form id="addDocumentForm" method="post" enctype="multipart/form-data" action="{% url 'assets:roads_streets_add_document' street.id %}">
|
|
{% csrf_token %}
|
|
|
|
<div class="mb-3">
|
|
<label for="fileInput" class="form-label">{% translate "Sélectionner des fichiers" %}</label>
|
|
<input type="file" id="fileInput" name="files" multiple class="form-control">
|
|
</div>
|
|
|
|
<div id="fileFieldsContainer">
|
|
<!-- Champs dynamiques injectés ici -->
|
|
</div>
|
|
|
|
<div class="modal-footer">
|
|
<button type="submit" class="btn btn-primary" id="documentSubmitButton">
|
|
{% translate "Ajouter" %}
|
|
<span class="spinner-border spinner-border-sm ms-2 d-none" role="status" aria-hidden="true" id="documentSubmitSpinner"></span>
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- Modal form delete document -->
|
|
<div class="modal fade" id="documentDeleteModal" tabindex="-1" aria-labelledby="documentDeleteModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog modal-dialog-centered">
|
|
<div class="modal-content">
|
|
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="documentDeleteModalLabel">{% translate "Confirmer la suppression" %}</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="{% translate 'Fermer' %}"></button>
|
|
</div>
|
|
|
|
<div class="modal-body">
|
|
<p>{% translate "Voulez-vous vraiment supprimer ce document ?" %}</p>
|
|
<p><strong id="deleteDocumentFileName">{% translate "Nom du fichier" %}</strong></p>
|
|
</div>
|
|
|
|
<div class="modal-footer">
|
|
<form method="post" id="deleteDocumentForm" action="">
|
|
{% csrf_token %}
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{% translate "Annuler" %}</button>
|
|
<button type="submit" class="btn btn-danger">{% translate "Supprimer" %}</button>
|
|
</form>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- Modal for document history -->
|
|
<div class="modal fade" id="documentHistoryModal" tabindex="-1" aria-labelledby="documentHistoryModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog modal-xl modal-dialog-scrollable">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="documentHistoryModalLabel">{% translate "Historique des documents" %}</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="{% translate 'Fermer' %}"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div id="documentHistoryContent" class="row g-3">
|
|
<!-- Contenu dynamique injecté ici -->
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<div class="card mb-4">
|
|
<div class="card-header">
|
|
<h4 data-bs-toggle="collapse" href="#assets_card_body" role="button">{% translate "Assets" %}</h4>
|
|
</div>
|
|
<div class="card-body collapse show" id="assets_card_body">
|
|
<ul class="nav nav-tabs" id="assetsTab" role="tablist">
|
|
<li class="nav-item" role="presentation">
|
|
<button class="nav-link active" id="assets-tree-tab" data-bs-toggle="tab" data-bs-target="#assets-tree-structure" type="button" role="tab" aria-controls="assets-tree-structure" aria-selected="true" style="color: black;">{% translate "Arborescence" %}</button>
|
|
</li>
|
|
<li class="nav-item" role="presentation">
|
|
<button class="nav-link" id="assets-archives-tab" data-bs-toggle="tab" data-bs-target="#assets-archives" type="button" role="tab" aria-controls="assets-archives" aria-selected="false" style="color: black;">{% translate "Archives" %}</button>
|
|
</li>
|
|
</ul>
|
|
<div class="tab-content my-2" id="assetsTabContent">
|
|
<div class="tab-pane fade show active" id="assets-tree-structure" role="tabpanel" aria-labelledby="assets-tree-tab">
|
|
<div class="row">
|
|
<div class="col-md-12">
|
|
<ul>
|
|
<li>
|
|
{% translate "Chaussées" %} ({{ assets.roadways.count }})
|
|
<ul>
|
|
{% for roadway in assets.roadways %}
|
|
<li>
|
|
<a class="mx-2" href="{% url 'assets:roads_assets_detail' 'roadway' roadway.id %}">{{ roadway.code }}</a>
|
|
{% if roadway.coating_type %}<span class="badge bg-info">{{ roadway.get_coating_type_display }}</span>{% endif %}
|
|
{% if roadway.quality_level %}<span class="badge bg-secondary">{% translate "Qualité" %}: {{ roadway.quality_level }}</span>{% endif %}
|
|
{% if roadway.area %}<span class="text-muted">({{ roadway.area|floatformat:2 }} m²)</span>{% endif %}
|
|
</li>
|
|
{% empty %}
|
|
<li class="text-muted">{% translate "Aucune chaussée" %}</li>
|
|
{% endfor %}
|
|
</ul>
|
|
</li>
|
|
<li>
|
|
{% translate "Trottoirs" %} ({{ assets.sidewalks.count }})
|
|
<ul>
|
|
{% for sidewalk in assets.sidewalks %}
|
|
<li>
|
|
<a class="mx-2" href="{% url 'assets:roads_assets_detail' 'roadsidewalk' sidewalk.id %}">{{ sidewalk.code }}</a>
|
|
{% if sidewalk.coating_type %}<span class="badge bg-info">{{ sidewalk.get_coating_type_display }}</span>{% endif %}
|
|
{% if sidewalk.quality_level %}<span class="badge bg-secondary">{% translate "Qualité" %}: {{ sidewalk.quality_level }}</span>{% endif %}
|
|
{% if sidewalk.area %}<span class="text-muted">({{ sidewalk.area|floatformat:2 }} m²)</span>{% endif %}
|
|
</li>
|
|
{% empty %}
|
|
<li class="text-muted">{% translate "Aucun trottoir" %}</li>
|
|
{% endfor %}
|
|
</ul>
|
|
</li>
|
|
<li>
|
|
{% translate "Mobilier urbain" %} ({{ assets.furnitures.count }})
|
|
<ul>
|
|
{% for furniture in assets.furnitures %}
|
|
<li>
|
|
<a class="mx-2" href="{% url 'assets:roads_assets_detail' 'roadfurniture' furniture.id %}">{{ furniture.code }}</a>
|
|
{% if furniture.model %}<span class="text-muted">{{ furniture.model.name }}</span>{% endif %}
|
|
</li>
|
|
{% empty %}
|
|
<li class="text-muted">{% translate "Aucun mobilier urbain" %}</li>
|
|
{% endfor %}
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="tab-pane fade" id="assets-archives" role="tabpanel" aria-labelledby="assets-archives-tab">
|
|
<p class="text-muted">{% translate "Aucun asset archivé" %}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<div class="card mb-4">
|
|
<div class="card-header">
|
|
<h4>{% translate "Interventions" %}</h4>
|
|
</div>
|
|
<div class="card-body">
|
|
<table id="interventions-table" class="table"
|
|
data-height="550"
|
|
data-pagination="true"
|
|
data-page-size="25"
|
|
data-click-to-select="true" >
|
|
<thead>
|
|
<tr>
|
|
<th data-field="actions" data-width="100"></th>
|
|
<th data-field="code">{% translate "Code" %}</th>
|
|
<th data-field="title">{% translate "Titre" %}</th>
|
|
<th data-field="begin_date">{% translate "Début" %}</th>
|
|
<th data-field="statut">{% translate "Statut" %}</th>
|
|
</tr>
|
|
<tbody>
|
|
{% for interv in interventions %}
|
|
<tr>
|
|
<td>
|
|
<a href="{% url 'interventions:interventions_index' %}{{ interv.id }}" type="button" class="btn btn-sm btn-light detail-btn" data-id="${row.id}" data-bs-toggle="tooltip" title="{% translate 'Détail' %}">
|
|
<i class="bi bi-info-circle"></i>
|
|
</a>
|
|
</td>
|
|
<td>{{ interv.code }}</td>
|
|
<td>{{ interv.title }}</td>
|
|
<td>{{ interv.begin_time|date:"d-m-Y H:i" }}</td>
|
|
<td>{{ interv.get_status_display }}</td>
|
|
</tr>
|
|
{% empty %}
|
|
<tr>
|
|
<td colspan="5" class="text-muted text-center">{% translate "Aucune intervention" %}</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</thead>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-4">
|
|
<div id="map">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{% endblock content%}
|
|
|
|
|
|
{% block script %}
|
|
{{ street.lon|json_script:"lon_value" }}
|
|
{{ street.lat|json_script:"lat_value" }}
|
|
{{ geom|json_script:"geom_value" }}
|
|
<script>
|
|
const roads_streets_url = "{% url 'assets:roads_streets' %}";
|
|
const document_history_url = "{% url 'assets:roads_streets_document_history' %}";
|
|
const feature_lon = JSON.parse(document.getElementById("lon_value").textContent);
|
|
const feature_lat = JSON.parse(document.getElementById("lat_value").textContent);
|
|
const geom = JSON.parse(document.getElementById("geom_value").textContent);
|
|
</script>
|
|
<!-- Turf.js (local) -->
|
|
<script src="{% static 'common/turf.min.js' %}"></script>
|
|
<script src="{% static 'assets/roads_street_detail.js' %}"></script>
|
|
{% endblock script %}
|