2026-01-27 10:00:05 +01:00

846 lines
35 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php include('include/headscript.php'); ?>
<!doctype html>
<html lang="it">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="assets/images/favicon-32x32.png" type="image/png" />
<?php include('cssinclude.php'); ?>
<title>Gestione Matrici - <?= htmlspecialchars($titlewebsite, ENT_QUOTES, 'UTF-8'); ?></title>
<!-- jQuery, Bootstrap, SweetAlert -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<!-- DataTables -->
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.6/css/dataTables.bootstrap5.min.css">
<script src="https://cdn.datatables.net/1.13.6/js/jquery.dataTables.min.js"></script>
<!-- Select2 -->
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
<link href="https://cdn.jsdelivr.net/npm/select2-bootstrap-5-theme@1.3.0/dist/select2-bootstrap-5-theme.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.full.min.js"></script>
<style>
body {
font-size: 1.05rem;
background: #f8fafc;
}
.card {
border-radius: 16px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}
.back-dashboard {
background-color: #b9ebc7 !important;
color: #1f2d3d !important;
border-radius: 10px;
font-weight: 600;
font-size: 1rem;
padding: 10px 18px;
}
.btn-add {
background-color: #198754;
color: #fff;
border-radius: 8px;
padding: 10px 20px;
}
.table thead {
background-color: #b9ebc7;
text-align: center;
}
.action-btn {
border: none;
background: none;
cursor: pointer;
font-size: 1.2rem;
margin: 0 4px;
}
.edit {
color: #0d6efd;
}
.delete {
color: #dc3545;
}
.linee {
color: #198754;
}
.mescole {
color: #ff9800;
}
.thumb-img:hover {
transform: scale(1.05);
transition: 0.2s;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
}
/* === DataTables search: make it stand out === */
.dataTables_wrapper .dataTables_filter {
position: relative;
margin-bottom: 12px;
}
.dataTables_wrapper .dataTables_filter label {
font-weight: 700;
color: #1f2d3d;
display: flex;
align-items: center;
gap: 10px;
justify-content: flex-end;
/* search allineato a destra */
}
/* input vero e proprio */
.dataTables_wrapper .dataTables_filter input {
width: 340px !important;
/* più grande */
max-width: 100%;
padding: 10px 14px !important;
border-radius: 12px !important;
border: 2px solid #198754 !important;
/* verde evidenza */
background: #fff !important;
box-shadow: 0 6px 18px rgba(25, 135, 84, 0.18);
outline: none !important;
transition: all .15s ease;
}
/* focus ancora più evidente */
.dataTables_wrapper .dataTables_filter input:focus {
border-color: #146c43 !important;
box-shadow: 0 0 0 0.2rem rgba(25, 135, 84, 0.25), 0 10px 22px rgba(25, 135, 84, 0.22) !important;
}
.dataTables_wrapper .dataTables_filter::after {
content: "🔎";
position: absolute;
right: 16px;
top: 50%;
transform: translateY(-50%);
pointer-events: none;
opacity: 0.7;
font-size: 16px;
}
/* spazio a destra per non “toccare” licona */
.dataTables_wrapper .dataTables_filter input {
padding-right: 42px !important;
}
/* --- FIX larghezze tabella matrici --- */
#tabellaMatrici {
table-layout: fixed;
/* rende fisse le larghezze */
width: 100% !important;
}
#tabellaMatrici th,
#tabellaMatrici td {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
/* evita che il testo allarghi */
vertical-align: middle;
}
/* Foto: più stretta */
#tabellaMatrici th:nth-child(1),
#tabellaMatrici td:nth-child(1) {
width: 90px;
max-width: 90px;
}
/* Nome: più largo */
#tabellaMatrici th:nth-child(2),
#tabellaMatrici td:nth-child(2) {
width: 320px;
max-width: 320px;
}
/* Cliente: più largo */
#tabellaMatrici th:nth-child(3),
#tabellaMatrici td:nth-child(3) {
width: 320px;
max-width: 320px;
}
/* Linee: media */
#tabellaMatrici th:nth-child(4),
#tabellaMatrici td:nth-child(4) {
width: 220px;
max-width: 220px;
}
/* Azioni: fissa */
#tabellaMatrici th:nth-child(5),
#tabellaMatrici td:nth-child(5) {
width: 170px;
max-width: 170px;
}
/* Immagine: non “sfora” mai nella cella */
#tabellaMatrici td:nth-child(1) img {
width: 70px;
/* puoi scendere a 60 */
height: 60px;
object-fit: cover;
}
</style>
</head>
<body>
<div class="wrapper toggled">
<?php include('include/navbar.php'); ?>
<?php include('include/topbar.php'); ?>
<div class="page-wrapper">
<div class="page-content">
<div class="card p-3">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="mb-0">Gestione elenco Profili</h5>
<button type="button" class="btn back-dashboard" onclick="location.href='production_dashboard.php'">↩️ Torna alla Dashboard</button>
</div>
<div class="card-body">
<div class="d-flex justify-content-between align-items-center mb-3">
<h6 class="fw-semibold mb-0">Elenco Completo</h6>
<button class="btn btn-add" data-bs-toggle="modal" data-bs-target="#addMatriceModal"> Aggiungi Matrice</button>
</div>
<!-- TABELLA -->
<div class="table-responsive">
<table id="tabellaMatrici" class="table table-striped align-middle text-center">
<thead>
<tr>
<th>Foto</th>
<th>Nome</th>
<th>Cliente</th>
<th>Linee</th>
<th>Azioni</th>
</tr>
</thead>
<tbody>
<?php
$db = DBHandlerSelect::getInstance();
$pdo = $db->getConnection();
$stmt = $pdo->query("
SELECT
m.*,
COALESCE(lg.linee_associate, '—') AS linee_associate,
COALESCE(mg.mescole_associate, '') AS mescole_associate,
COALESCE(mg.mescole_count, 0) AS mescole_count
FROM matrice m
LEFT JOIN (
SELECT
ml.idmatrice,
GROUP_CONCAT(pl.name ORDER BY pl.name SEPARATOR ', ') AS linee_associate
FROM matrici_lines ml
JOIN production_lines pl ON pl.id = ml.idlinea
GROUP BY ml.idmatrice
) lg ON lg.idmatrice = m.id
LEFT JOIN (
SELECT
mm.idmatrice,
GROUP_CONCAT(ms.nome ORDER BY ms.nome SEPARATOR ', ') AS mescole_associate,
COUNT(*) AS mescole_count
FROM matrici_mescole mm
JOIN mescole ms ON ms.id = mm.idmescola
GROUP BY mm.idmatrice
) mg ON mg.idmatrice = m.id
ORDER BY m.id DESC
");
function formatDateIT($d)
{
if (!$d || $d == '0000-00-00') return '';
return date("d/m/Y", strtotime($d));
}
if ($stmt->rowCount() === 0) {
echo "<tr><td colspan='5' class='text-muted'>Nessuna matrice presente</td></tr>";
} else {
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$dataIT = formatDateIT($row['data_produzione']);
// gestione foto
$foto = $row['photo'] ?? '';
$pathFoto = "photos/matrici/" . $foto;
$placeholder = "assets/images/no-photo.png";
if ($foto && file_exists($pathFoto)) {
$thumb = $pathFoto;
$hasPhoto = true;
} else {
$thumb = $placeholder;
$hasPhoto = false;
}
echo "<tr>";
// colonna FOTO
// colonna FOTO (robusta: NP appare solo se l'immagine non si carica)
$imgSrc = $hasPhoto ? $thumb : ''; // se non c'è foto, src vuoto → trigger onerror
echo "<td class='foto-cell'>
<img src='" . htmlspecialchars($imgSrc, ENT_QUOTES) . "'
class='thumb-img'
data-full='" . htmlspecialchars($thumb, ENT_QUOTES) . "'
style='height:60px; cursor:pointer; border-radius:6px; " . ($hasPhoto ? "" : "display:none;") . "'
title='" . ($hasPhoto ? "Clicca per ingrandire" : "") . "'
onerror=\"
this.style.display='none';
this.closest('td').querySelector('.no-photo').style.display='inline-block';
\">
<span class='no-photo text-muted fw-semibold' style='display:" . ($hasPhoto ? "none" : "inline-block") . ";'>NP</span>
</td>";
// colonna NOME (con tooltip)
echo "<td title='" . htmlspecialchars($row['nome'], ENT_QUOTES) . "'>"
. htmlspecialchars($row['nome'])
. "</td>";
// colonna CLIENTE (con tooltip)
echo "<td title='" . htmlspecialchars($row['cliente'], ENT_QUOTES) . "'>"
. htmlspecialchars($row['cliente'])
. "</td>";
// colonna LINEE
$lineeTxt = $row['linee_associate'] ?? '—';
$mescoleTxt = $row['mescole_associate'] ?? '';
$mescoleCount = (int)($row['mescole_count'] ?? 0);
$btnMescole = '';
if ($mescoleCount > 0) {
$btnMescole = " <button type='button'
class='btn btn-sm btn-outline-secondary ms-2 show-mescole'
data-nome='" . htmlspecialchars($row['nome'], ENT_QUOTES) . "'
data-mescole='" . htmlspecialchars($mescoleTxt, ENT_QUOTES) . "'
data-bs-toggle='tooltip' data-bs-title='Vedi mescole associate'>
<i class='fa-solid fa-flask'></i>
</button>";
}
echo "<td title='" . htmlspecialchars($lineeTxt, ENT_QUOTES) . "'>"
. htmlspecialchars($lineeTxt)
. $btnMescole
. "</td>";
// colonna AZIONI
echo "<td>
<button class='action-btn edit'
data-id='{$row['id']}'
data-nome='" . htmlspecialchars($row['nome'], ENT_QUOTES) . "'
data-cliente='" . htmlspecialchars($row['cliente'], ENT_QUOTES) . "'
data-data='{$dataIT}'
data-bs-toggle='tooltip' data-bs-title='Modifica'>
<i class='fa-solid fa-pen-to-square'></i>
</button>
<button class='action-btn delete'
data-id='{$row['id']}'
data-bs-toggle='tooltip' data-bs-title='Elimina'>
<i class='fa-solid fa-trash'></i>
</button>
<button class='action-btn linee'
data-id='{$row['id']}'
data-nome='" . htmlspecialchars($row['nome'], ENT_QUOTES) . "'
data-bs-toggle='tooltip' data-bs-title='Linee associate'>
<i class='fa-solid fa-sitemap'></i>
</button>
<button class='action-btn mescole'
data-id='{$row['id']}'
data-nome='" . htmlspecialchars($row['nome'], ENT_QUOTES) . "'
data-bs-toggle='tooltip' data-bs-title='Mescole associate'>
<i class='fa-solid fa-flask'></i>
</button>
</td>";
echo "</tr>";
}
}
?>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<?php include('include/footer.php'); ?>
</div>
<!-- MODALE AGGIUNTA / MODIFICA MATRICE -->
<div class="modal fade" id="addMatriceModal" tabindex="-1">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header" style="background-color:#b9ebc7;">
<h5 class="modal-title">Aggiungi / Modifica Matrice</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<form id="addMatriceForm">
<input type="hidden" id="idMatriceEdit">
<div class="mb-3">
<label class="fw-semibold">Nome Matrice</label>
<input type="text" class="form-control" id="nomeMatrice" required>
</div>
<div class="mb-3">
<label class="fw-semibold">Cliente</label>
<input type="text" class="form-control" id="clienteMatrice">
</div>
<div class="mb-3">
<label class="fw-semibold">Data</label>
<input type="text" class="form-control" id="dataMatrice" placeholder="dd/mm/yyyy">
</div>
<div class="text-center">
<button type="submit" class="btn btn-add">💾 Salva</button>
</div>
</form>
</div>
</div>
</div>
</div>
<!-- MODALE LINEE ASSOCIATE -->
<div class="modal fade" id="matriceLineeModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header" style="background-color:#b9ebc7;">
<h5 class="modal-title">Linee associate</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<input type="hidden" id="ml_idmatrice">
<div class="mb-2">
<div class="fw-semibold" id="ml_matrice_name" style="color:#1f2d3d;"></div>
<small class="text-muted">Seleziona una o più linee di produzione</small>
</div>
<div class="mb-3">
<label class="fw-semibold">Linee</label>
<select id="ml_linee" class="form-select" multiple="multiple" style="width:100%;"></select>
</div>
<div class="text-center">
<button type="button" class="btn btn-add" id="ml_save_btn">💾 Salva Linee</button>
</div>
</div>
</div>
</div>
</div>
<!-- MODALE MESCOLE ASSOCIATE -->
<div class="modal fade" id="matriceMescoleModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header" style="background-color:#b9ebc7;">
<h5 class="modal-title">Mescole associate</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<input type="hidden" id="mm_idmatrice">
<div class="mb-2">
<div class="fw-semibold" id="mm_matrice_name" style="color:#1f2d3d;"></div>
<small class="text-muted">Seleziona una o più mescole</small>
</div>
<div class="mb-3">
<label class="fw-semibold">Mescole</label>
<select id="mm_mescole" class="form-select" multiple="multiple" style="width:100%;"></select>
</div>
<div class="text-center">
<button type="button" class="btn btn-add" id="mm_save_btn">💾 Salva Mescole</button>
</div>
</div>
</div>
</div>
</div>
<?php include('jsinclude.php'); ?>
<script>
/* Format date dd/mm/yyyy → yyyy-mm-dd */
function convertToMySQLDate(dateStr) {
if (!dateStr) return "";
const parts = dateStr.split("/");
if (parts.length !== 3) return "";
return parts[2] + "-" + parts[1] + "-" + parts[0];
}
$(document).ready(function() {
$('#tabellaMatrici').DataTable({
order: [
[0, 'desc']
],
columnDefs: [{
targets: 0, // colonna FOTO
orderable: false,
searchable: false,
render: function(data, type, row, meta) {
return data; // lascia l'HTML così com'è (img + NP)
}
}],
pageLength: 50,
language: {
url: 'https://cdn.datatables.net/plug-ins/1.13.6/i18n/it-IT.json'
}
});
// Rendiamo più chiaro il filtro
$('#tabellaMatrici_filter label').contents().filter(function() {
return this.nodeType === 3; // text node
}).first().replaceWith('Cerca: ');
// Placeholder nell'input
$('#tabellaMatrici_filter input')
.attr('placeholder', 'Nome matrice, cliente…')
.addClass('form-control'); // opzionale: look Bootstrap coerente
// === EDIT MATRICE ===
$(document).on("click", ".edit", function() {
$("#idMatriceEdit").val($(this).data("id"));
$("#nomeMatrice").val($(this).data("nome"));
$("#clienteMatrice").val($(this).data("cliente"));
$("#dataMatrice").val($(this).data("data"));
$("#addMatriceModal").modal("show");
});
// === SALVA MATRICE ===
$("#addMatriceForm").on("submit", function(e) {
e.preventDefault();
let id = $("#idMatriceEdit").val();
let nome = $("#nomeMatrice").val().trim();
let cliente = $("#clienteMatrice").val().trim();
let dataIT = $("#dataMatrice").val().trim();
let dataSQL = convertToMySQLDate(dataIT);
fetch("save_matrice.php", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
body: "id=" + id + "&nome=" + encodeURIComponent(nome) + "&cliente=" + encodeURIComponent(cliente) + "&data=" + encodeURIComponent(dataSQL)
})
.then(r => r.json())
.then(data => {
Swal.fire({
icon: data.success ? "success" : "error",
title: data.success ? "Salvato!" : "Errore",
text: data.message || ""
}).then(() => location.reload());
});
});
// === DELETE MATRICE ===
$(document).on("click", ".delete", function() {
const id = $(this).data("id");
Swal.fire({
icon: "warning",
title: "Eliminare questa matrice?",
showCancelButton: true,
confirmButtonColor: "#d33"
}).then(res => {
if (res.isConfirmed) {
fetch("delete_matrice.php?id=" + id)
.then(r => r.json())
.then(data => {
Swal.fire({
icon: data.success ? "success" : "error",
title: data.success ? "Eliminata!" : "Errore"
}).then(() => location.reload());
});
}
});
});
// Bootstrap 5 tooltips
document.querySelectorAll('[data-bs-toggle="tooltip"]').forEach(el => new bootstrap.Tooltip(el));
// === LINEE ASSOCIATE (MODALE) ===
// init Select2 (dentro modal)
$('#ml_linee').select2({
theme: 'bootstrap-5',
dropdownParent: $('#matriceLineeModal'),
placeholder: 'Seleziona le linee...'
});
// open modal + load data
$(document).on("click", ".linee", function() {
const idmatrice = $(this).data("id");
const nome = $(this).data("nome") || "";
$("#ml_idmatrice").val(idmatrice);
$("#ml_matrice_name").text(nome);
// pulizia select
const $sel = $("#ml_linee");
$sel.empty().trigger("change");
fetch("get_matrice_lines.php?id=" + encodeURIComponent(idmatrice))
.then(r => r.json())
.then(data => {
if (!data.success) {
Swal.fire({
icon: "error",
title: "Errore",
text: data.message || "Impossibile caricare le linee"
});
return;
}
// riempi opzioni linee
data.lines.forEach(l => {
const label = `Linea ${l.line_number} - ${l.name}`;
const opt = new Option(label, l.id, false, false);
$sel.append(opt);
});
// seleziona quelle già associate
$sel.val((data.selected_ids || []).map(String)).trigger("change");
// apri modale (BS5)
const modal = new bootstrap.Modal(document.getElementById('matriceLineeModal'));
modal.show();
});
});
// save associations
$("#ml_save_btn").on("click", function() {
const idmatrice = $("#ml_idmatrice").val();
const selected = $("#ml_linee").val() || []; // array di idlinea
fetch("save_matrice_lines.php", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
body: "idmatrice=" + encodeURIComponent(idmatrice) +
"&idlinee=" + encodeURIComponent(JSON.stringify(selected))
})
.then(r => r.json())
.then(data => {
Swal.fire({
icon: data.success ? "success" : "error",
title: data.success ? "Salvato!" : "Errore",
text: data.message || ""
}).then(() => {
if (data.success) {
bootstrap.Modal.getInstance(document.getElementById('matriceLineeModal')).hide();
location.reload(); // refresh tabella (render PHP)
}
});
});
});
// === MESCOLE ASSOCIATE (MODALE) ===
// init Select2 (dentro modal)
$('#mm_mescole').select2({
theme: 'bootstrap-5',
dropdownParent: $('#matriceMescoleModal'),
placeholder: 'Cerca e seleziona le mescole...',
minimumResultsForSearch: 0, // <-- search sempre visibile
width: '100%'
});
// open modal + load data
$(document).on("click", ".mescole", function() {
const idmatrice = $(this).data("id");
const nome = $(this).data("nome") || "";
$("#mm_idmatrice").val(idmatrice);
$("#mm_matrice_name").text(nome);
const $sel = $("#mm_mescole");
$sel.empty().trigger("change");
fetch("get_matrice_mescole.php?id=" + encodeURIComponent(idmatrice))
.then(r => r.json())
.then(data => {
if (!data.success) {
Swal.fire({
icon: "error",
title: "Errore",
text: data.message || "Impossibile caricare le mescole"
});
return;
}
// riempi opzioni mescole
data.mescole.forEach(m => {
const label = m.nomeuscita ? `${m.nome} (${m.nomeuscita})` : m.nome;
const opt = new Option(label, m.id, false, false);
$sel.append(opt);
});
// seleziona quelle già associate
$sel.val((data.selected_ids || []).map(String)).trigger("change");
// apri modale (BS5)
const modal = new bootstrap.Modal(document.getElementById('matriceMescoleModal'));
modal.show();
});
});
// save associations
$("#mm_save_btn").on("click", function() {
const idmatrice = $("#mm_idmatrice").val();
const selected = $("#mm_mescole").val() || []; // array di idmescola
fetch("save_matrice_mescole.php", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
body: "idmatrice=" + encodeURIComponent(idmatrice) +
"&idmescole=" + encodeURIComponent(JSON.stringify(selected))
})
.then(r => r.json())
.then(data => {
Swal.fire({
icon: data.success ? "success" : "error",
title: data.success ? "Salvato!" : "Errore",
text: data.message || ""
}).then(() => {
if (data.success) {
bootstrap.Modal.getInstance(document.getElementById('matriceMescoleModal')).hide();
location.reload(); // refresh tabella (render PHP)
}
});
});
});
// click: mostra elenco mescole associate (read-only)
$(document).on('click', '.show-mescole', function() {
const nome = $(this).data('nome') || '';
const mescole = $(this).data('mescole') || '';
$("#mlm_matrice_name").text(nome);
if (!mescole.trim()) {
$("#mlm_list").html("<span class='text-muted'>Nessuna mescola associata</span>");
} else {
// elenco in badge
const items = mescole.split(',').map(s => s.trim()).filter(Boolean);
$("#mlm_list").html(items.map(x => `<span class="badge bg-secondary me-1 mb-1">${x}</span>`).join(''));
}
const modal = new bootstrap.Modal(document.getElementById('mescoleListModal'));
modal.show();
});
});
// Apri lightbox
$(document).on("click", ".thumb-img", function() {
let full = $(this).data("full");
$("#bigImg").attr("src", full);
$("#bigView")
.css("display", "flex") // diventa flex
.hide()
.fadeIn(200); // fade-in elegante
});
// Chiudi cliccando ovunque sull'overlay
$(document).on("click", "#bigView", function() {
$(this).fadeOut(200, function() {
$(this).css("display", "none");
});
});
</script>
<!-- MODALE FOTO GRANDE -->
<div class="modal fade" id="fotoModal" tabindex="-1">
<div class="modal-dialog modal-dialog-centered modal-lg">
<div class="modal-content p-0" style="background:transparent; border:none;">
<img id="fotoGrande" src="" style="width:60vw; max-height:80vh; object-fit:contain; border-radius:10px;">
</div>
</div>
</div>
<div id="bigView"
style="display:none;
position:fixed;
top:0; left:0;
width:100vw; height:100vh;
background:rgba(0,0,0,0.9);
z-index:9999;
justify-content:center;
align-items:center;">
<img id="bigImg" src=""
style="max-width:70vw; max-height:90vh; border-radius:12px;">
</div>
<!-- MODALE LISTA MESCOLE ASSOCIATE (READ-ONLY) -->
<div class="modal fade" id="mescoleListModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header" style="background-color:#b9ebc7;">
<h5 class="modal-title">Mescole associate</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div class="fw-semibold mb-2" id="mlm_matrice_name" style="color:#1f2d3d;"></div>
<div id="mlm_list" class="text-muted"></div>
</div>
</div>
</div>
</div>
</body>
</html>