Added front-end entity filter and details button functionality

This commit is contained in:
2025-12-14 20:37:18 +01:00
parent 6145d32040
commit 3329712548

View File

@@ -99,6 +99,7 @@
<div class="d-flex justify-content-between align-items-center mb-2"> <div class="d-flex justify-content-between align-items-center mb-2">
<strong>Entities</strong> <strong>Entities</strong>
<input <input
id="entitiesFilter"
type="text" type="text"
class="form-control form-control-sm w-25" class="form-control form-control-sm w-25"
placeholder="filter" placeholder="filter"
@@ -134,10 +135,66 @@
</div> </div>
</div> </div>
<!-- Entity Details Modal -->
<div class="modal fade" id="entityDetailsModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-lg modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="entityDetailsTitle">Entity Details</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<!-- Attributes -->
<h6>Attributes</h6>
<table class="table table-sm table-bordered mb-4">
<thead>
<tr>
<th>Key</th>
<th>Value</th>
</tr>
</thead>
<tbody id="entityAttributesBody">
</tbody>
</table>
<!-- Datapoints -->
<h6>Datapoints</h6>
<table class="table table-sm table-striped">
<thead>
<tr>
<th>Name</th>
<th>ProbMethod</th>
<th>SimilarityMethod</th>
</tr>
</thead>
<tbody id="entityDatapointsBody">
</tbody>
</table>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
Close
</button>
</div>
</div>
</div>
</div>
<script> <script>
var domains = JSON.parse('@Html.Raw(System.Text.Json.JsonSerializer.Serialize(domains))'); var domains = JSON.parse('@Html.Raw(System.Text.Json.JsonSerializer.Serialize(domains))');
var entities = null; var entities = null;
document.addEventListener('DOMContentLoaded', () => {
const filterInput = document.getElementById('entitiesFilter');
filterInput.addEventListener('input', () => {
populateEntitiesTable(filterInput.value);
});
});
function selectDomain(domainKey) { function selectDomain(domainKey) {
// Deselect all domain items // Deselect all domain items
document.querySelectorAll('.domain-item').forEach(item => { document.querySelectorAll('.domain-item').forEach(item => {
@@ -176,13 +233,17 @@
tableBody.innerHTML = ''; tableBody.innerHTML = '';
} }
function populateEntitiesTable() { function populateEntitiesTable(filterText = '') {
if (!entities) return; if (!entities) return;
var tableBody = document.querySelector('#entitiesTable tbody'); var tableBody = document.querySelector('#entitiesTable tbody');
clearEntitiesTable(); tableBody.innerHTML = '';
entities.forEach(entity => { const normalizedFilter = filterText.toLowerCase();
entities
.filter(e => e.Name.toLowerCase().includes(normalizedFilter))
.forEach(entity => {
var row = document.createElement('tr'); var row = document.createElement('tr');
var nameCell = document.createElement('td'); var nameCell = document.createElement('td');
@@ -193,6 +254,11 @@
var detailsButton = document.createElement('button'); var detailsButton = document.createElement('button');
detailsButton.className = 'btn btn-primary btn-sm'; detailsButton.className = 'btn btn-primary btn-sm';
detailsButton.textContent = 'Details'; detailsButton.textContent = 'Details';
detailsButton.setAttribute("data-index", entities.findIndex(en => en == entity));
detailsButton.addEventListener('click', () => {
showEntityDetails(entity);
});
actionCell.appendChild(detailsButton); actionCell.appendChild(detailsButton);
row.appendChild(actionCell); row.appendChild(actionCell);
@@ -214,4 +280,53 @@
if (element == null) element = document; if (element == null) element = document;
element.querySelector('.spinner').classList.add('d-none'); element.querySelector('.spinner').classList.add('d-none');
} }
function showEntityDetails(entity) {
// Title
document.getElementById('entityDetailsTitle').innerText = entity.Name;
// Attributes
const attrBody = document.getElementById('entityAttributesBody');
attrBody.innerHTML = '';
const attributes = entity.Attributes || {};
const attrKeys = Object.keys(attributes);
if (attrKeys.length === 0) {
attrBody.innerHTML = `
<tr>
<td colspan="2" class="text-muted text-center">No attributes</td>
</tr>`;
} else {
attrKeys.forEach(key => {
const row = document.createElement('tr');
attributeKV = attributes[key];
row.innerHTML = `
<td>${attributeKV["Name"]}</td>
<td>${attributeKV["Value"]}</td>
`;
attrBody.appendChild(row);
});
}
// Datapoints
const dpBody = document.getElementById('entityDatapointsBody');
dpBody.innerHTML = '';
(entity.Datapoints || []).forEach(dp => {
const row = document.createElement('tr');
row.innerHTML = `
<td>${dp.Name}</td>
<td>${dp.ProbMethod}</td>
<td>${dp.SimilarityMethod}</td>
`;
dpBody.appendChild(row);
});
// Show modal
const modal = new bootstrap.Modal(
document.getElementById('entityDetailsModal')
);
modal.show();
}
</script> </script>