feat: implement unified assets and locations management system via new index page and associated scripts

This commit is contained in:
Karl Determe 2026-08-25 11:35:45 +02:00
parent e6bc68ee42
commit 97edbde803
3 changed files with 48 additions and 51 deletions

View file

@ -712,7 +712,7 @@ $(document).ready(function () {
} }
function calcHeight() { function calcHeight() {
return Math.max(300, $(window).height() - 250); return Math.max(300, $(window).height() - 210);
} }
$('#unified-table').bootstrapTable({ $('#unified-table').bootstrapTable({
@ -1171,7 +1171,7 @@ $(document).ready(function () {
document.getElementById('col-table').className = 'col-md-6'; document.getElementById('col-table').className = 'col-md-6';
const colMap = document.getElementById('col-map'); const colMap = document.getElementById('col-map');
colMap.className = 'col-md-6'; colMap.className = 'col-md-6';
colMap.style.cssText = 'position: relative; margin-top: 50px;'; colMap.style.cssText = 'position: relative;';
setLayoutActive('both'); setLayoutActive('both');
}); });
document.getElementById('layout-btn-map').addEventListener('click', function () { document.getElementById('layout-btn-map').addEventListener('click', function () {

View file

@ -133,10 +133,10 @@
{% with default_tab_value=default_tab|default:'locations' %} {% with default_tab_value=default_tab|default:'locations' %}
<ul class="nav nav-tabs" id="tablesTab" role="tablist"> <ul class="nav nav-tabs" id="tablesTab" role="tablist">
<li class="nav-item mt-1" role="presentation"> <li class="nav-item" role="presentation">
<button class="nav-link {% if default_tab_value != 'assets' %}active{% endif %}" id="locations-table-tab" data-bs-toggle="tab" data-bs-target="#locations-table-content" type="button" role="tab" aria-controls="locations-table" aria-selected="{% if default_tab_value != 'assets' %}true{% else %}false{% endif %}">{{ locations_tab_title }}</button> <button class="nav-link {% if default_tab_value != 'assets' %}active{% endif %}" id="locations-table-tab" data-bs-toggle="tab" data-bs-target="#locations-table-content" type="button" role="tab" aria-controls="locations-table" aria-selected="{% if default_tab_value != 'assets' %}true{% else %}false{% endif %}">{{ locations_tab_title }}</button>
</li> </li>
<li class="nav-item mt-1 {% if preventive_draft_id and preventive_element_type == 'locations' %} d-none {% endif %}" role="presentation"> <li class="nav-item {% if preventive_draft_id and preventive_element_type == 'locations' %} d-none {% endif %}" role="presentation">
<button class="nav-link {% if default_tab_value == 'assets' %}active{% endif %}" id="assets-table-tab" data-bs-toggle="tab" data-bs-target="#assets-table-content" type="button" role="tab" aria-controls="assets-table" aria-selected="{% if default_tab_value == 'assets' %}true{% else %}false{% endif %}">{{ locations_assets_title }}</button> <button class="nav-link {% if default_tab_value == 'assets' %}active{% endif %}" id="assets-table-tab" data-bs-toggle="tab" data-bs-target="#assets-table-content" type="button" role="tab" aria-controls="assets-table" aria-selected="{% if default_tab_value == 'assets' %}true{% else %}false{% endif %}">{{ locations_assets_title }}</button>
</li> </li>
{% block tab_actions %}{% endblock %} {% block tab_actions %}{% endblock %}
@ -239,7 +239,7 @@
</div> </div>
{% endwith %} {% endwith %}
</div> </div>
<div id="col-map" class="{% if request.user.config.assets_list_layout == 'table_only' %}d-none{% elif request.user.config.assets_list_layout == 'map_only' %}col-12{% else %}col-md-6{% endif %}" style="position: relative; margin-top: 50px;"> <div id="col-map" class="{% if request.user.config.assets_list_layout == 'table_only' %}d-none{% elif request.user.config.assets_list_layout == 'map_only' %}col-12{% else %}col-md-6{% endif %}" style="position: relative;">
<!-- Panneau d'information pour les commentaires et assets --> <!-- Panneau d'information pour les commentaires et assets -->
<div id="info-panel"> <div id="info-panel">
<div class="panel-header"> <div class="panel-header">

View file

@ -377,46 +377,9 @@
</div> </div>
{% endif %} {% endif %}
<div id="unified-load-warning" class="alert alert-warning d-none py-2 mb-2" role="alert"></div> <div class="position-relative">
{# Layout selection buttons + Répertoires - aligned to the right #}
{# ─── Control block: Search widget + Layout buttons ──────────────────────── #} <div class="position-absolute top-0 end-0 mt-2 d-flex align-items-center gap-2" style="z-index: 10;">
<div class="d-flex align-items-center mb-2 position-relative" style="min-height: 40px;">
{# Search widget - perfectly centered horizontally #}
<div id="assets-search-widget" class="position-absolute start-50 translate-middle-x" style="z-index: 10;">
<div class="input-group" style="flex-wrap:nowrap;">
<div style="position:relative; display:flex;">
<input type="text" id="assets-search-input" class="form-control form-control-sm"
style="width:320px; border-radius:20px 0 0 20px; border-color:#dee2e6; padding-right:1.6rem;"
placeholder="{% translate 'Code, nom, type…' %}">
<button type="button" id="assets-search-clear"
style="position:absolute; right:4px; top:50%; transform:translateY(-50%);
background:none; border:none; padding:0 2px; line-height:1;
color:#adb5bd; cursor:pointer; visibility:hidden;"
title="{% translate 'Effacer' %}">
<i class="bi bi-x-lg" style="font-size:0.7rem;"></i>
</button>
</div>
<span class="input-group-text bg-white px-1" style="border-left:0; border-right:0; border-color:#dee2e6;">
<div class="btn-group btn-group-sm" role="group">
<input type="radio" class="btn-check" name="assets-search-mode" id="assets-search-mode-and" value="and" checked>
<label class="btn btn-outline-secondary py-0 px-2" for="assets-search-mode-and"
data-bs-toggle="tooltip" data-bs-placement="top"
title="{% translate 'Tous les mots recherchés doivent être présents' %}">{% translate "ET" %}</label>
<input type="radio" class="btn-check" name="assets-search-mode" id="assets-search-mode-or" value="or">
<label class="btn btn-outline-secondary py-0 px-2" for="assets-search-mode-or"
data-bs-toggle="tooltip" data-bs-placement="top"
title="{% translate 'Au moins un des mots recherchés doit être présent' %}">{% translate "OU" %}</label>
</div>
</span>
<button class="btn btn-sm" type="button" id="assets-search-btn"
style="border-radius:0 20px 20px 0; border:1px solid #dee2e6; border-left:0; background:white; color:#495057;">
<i class="bi bi-search"></i>
</button>
</div>
</div>
{# Layout selection buttons - aligned to the right #}
<div class="ms-auto d-flex align-items-center gap-2" style="z-index: 10;">
{# Dropdown Tableaux spécifiques (générique selon les thématiques accessibles) #} {# Dropdown Tableaux spécifiques (générique selon les thématiques accessibles) #}
{% if specific_tables %} {% if specific_tables %}
<div class="dropdown"> <div class="dropdown">
@ -443,7 +406,7 @@
</div> </div>
{% endif %} {% endif %}
<div class="btn-group" role="group"> <div class="btn-group" role="group" aria-label="{% translate 'Sélection de la vue' %}">
<button id="layout-btn-table" class="btn btn-light" type="button" title="{% translate 'Vue tableau uniquement' %}"> <button id="layout-btn-table" class="btn btn-light" type="button" title="{% translate 'Vue tableau uniquement' %}">
<i class="bi bi-table"></i> <i class="bi bi-table"></i>
</button> </button>
@ -455,16 +418,50 @@
</button> </button>
</div> </div>
</div> </div>
</div>
<div class="position-relative"> {# Search widget - perfectly centered horizontally #}
<div class="row mt-2" style="height: calc(100vh - 160px);"> <div id="assets-search-widget"
style="position:absolute; top:4px; left:50%; transform:translateX(-50%); z-index:10; pointer-events:none; max-width:calc(100% - 360px);">
<div class="input-group" style="pointer-events:auto; flex-wrap:nowrap;">
<div style="position:relative; display:flex; width:360px; max-width:100%; min-width:60px;">
<input type="text" id="assets-search-input" class="form-control form-control-sm"
style="width:100%; border-radius:20px 0 0 20px; border-color:#dee2e6; padding-right:1.6rem;"
placeholder="{% translate 'Code, nom, type…' %}">
<button type="button" id="assets-search-clear"
style="position:absolute; right:4px; top:50%; transform:translateY(-50%);
background:none; border:none; padding:0 2px; line-height:1;
color:#adb5bd; cursor:pointer; visibility:hidden;"
title="{% translate 'Effacer' %}">
<i class="bi bi-x-lg" style="font-size:0.7rem;"></i>
</button>
</div>
<span class="input-group-text bg-white px-1" style="border-left:0; border-right:0; border-color:#dee2e6; flex-shrink:0;">
<div class="btn-group btn-group-sm" role="group">
<input type="radio" class="btn-check" name="assets-search-mode" id="assets-search-mode-and" value="and" checked>
<label class="btn btn-outline-secondary py-0 px-2" for="assets-search-mode-and"
data-bs-toggle="tooltip" data-bs-placement="top"
title="{% translate 'Tous les mots recherchés doivent être présents' %}">{% translate "ET" %}</label>
<input type="radio" class="btn-check" name="assets-search-mode" id="assets-search-mode-or" value="or">
<label class="btn btn-outline-secondary py-0 px-2" for="assets-search-mode-or"
data-bs-toggle="tooltip" data-bs-placement="top"
title="{% translate 'Au moins un des mots recherchés doit être présent' %}">{% translate "OU" %}</label>
</div>
</span>
<button class="btn btn-sm px-3" type="button" id="assets-search-btn"
style="border-radius:0 20px 20px 0; border:1px solid #dee2e6; border-left:0; background:white; color:#495057; flex-shrink:0;"
title="{% translate 'Rechercher' %}">
<i class="bi bi-search"></i>
</button>
</div>
</div>
<div class="row mt-2" style="height: calc(100vh - 130px);">
{# ─── Table column ───────────────────────────────────────────────── #} {# ─── Table column ───────────────────────────────────────────────── #}
<div id="col-table" class="col-md-6 d-flex flex-column" style="max-height: calc(100vh - 160px);"> <div id="col-table" class="col-md-6 d-flex flex-column" style="max-height: calc(100vh - 130px);">
{# Tab nav with + and filter buttons #} {# Tab nav with + and filter buttons #}
<ul class="nav nav-tabs flex-shrink-0"> <ul class="nav nav-tabs flex-shrink-0" id="tablesTab" role="tablist">
<li class="nav-item" role="presentation"> <li class="nav-item" role="presentation">
<button class="nav-link active" type="button"> <button class="nav-link active" type="button">
<i class="bi bi-layers me-1"></i>{% translate "Assets" %} <i class="bi bi-layers me-1"></i>{% translate "Assets" %}