350 lines
15 KiB
Smarty
350 lines
15 KiB
Smarty
<!-- Modal - Relationen tabellarisch -->
|
||
<div class="modal fade" id="RelationsModal" tabindex="-1" aria-labelledby="RelationsModalLabel" aria-hidden="true">
|
||
<div class="modal-dialog modal-lg" style="max-width: 900px;">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h5 class="modal-title" id="RelationsModalHeadline">
|
||
<i class="fas fa-table"></i> Relationen
|
||
</h5>
|
||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Schließen"></button>
|
||
</div>
|
||
<div class="modal-body">
|
||
|
||
<!-- Term-Info -->
|
||
<div class="relations-modal-info mb-3">
|
||
<div class="row">
|
||
<div class="col-md-6">
|
||
<label class="form-label fw-bold">Begriff</label>
|
||
<input type="text" id="relations_modal_term" class="form-control" disabled />
|
||
</div>
|
||
<div class="col-md-2">
|
||
<label class="form-label fw-bold">ID</label>
|
||
<input type="text" id="relations_modal_id" class="form-control" disabled />
|
||
</div>
|
||
<div class="col-md-2">
|
||
<label class="form-label fw-bold">Deskriptor</label>
|
||
<input type="text" id="relations_modal_descriptor" class="form-control" disabled />
|
||
</div>
|
||
<div class="col-md-2">
|
||
<label class="form-label fw-bold">DSpace</label>
|
||
<div id="relations_modal_dspace" class="form-control" style="background: #e9ecef;">
|
||
<span class="text-muted">–</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Lade-Anzeige -->
|
||
<div id="relations_modal_loading" class="text-center py-4" style="display: none;">
|
||
<div class="spinner-border spinner-border-sm text-primary me-2" role="status"></div>
|
||
<span class="text-muted">Lade Relationen...</span>
|
||
</div>
|
||
|
||
<!-- Relationen-Tabelle -->
|
||
<div id="relations_modal_content" style="display: none;">
|
||
<div class="table-responsive" style="border: 1px solid #dee2e6; border-radius: 0.375rem; overflow: hidden;">
|
||
<table class="table table-sm table-hover table-bordered mb-0">
|
||
<thead class="table-light">
|
||
<tr>
|
||
<th style="width: 120px;">Typ</th>
|
||
<th>Begriff</th>
|
||
<th style="width: 80px;" class="text-center">ID</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="relations_modal_body">
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Keine Relationen -->
|
||
<div id="relations_modal_empty" class="text-center py-4 text-muted" style="display: none;">
|
||
<i class="fas fa-info-circle me-1"></i> Keine Relationen vorhanden.
|
||
</div>
|
||
|
||
<!-- Synonyme-Bereich (nur bei Subjects) -->
|
||
<div id="relations_modal_synonyms" style="display: none; margin-top: 15px;">
|
||
<h6 class="mb-2"><i class="fas fa-equals me-1" style="color: #e91e63;"></i> Synonyme</h6>
|
||
<div class="table-responsive" style="border: 1px solid #dee2e6; border-radius: 0.375rem; overflow: hidden;">
|
||
<table class="table table-sm table-hover table-bordered mb-0">
|
||
<thead class="table-light">
|
||
<tr>
|
||
<th style="width: 120px;">Typ</th>
|
||
<th>Begriff</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="relations_modal_synonyms_body">
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<div class="modal-footer">
|
||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
|
||
<i class="fas fa-times"></i> schliessen
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<style>
|
||
.relations-modal-info {
|
||
background: var(--bg-light, #f8f9fa);
|
||
border-radius: 8px;
|
||
padding: 15px;
|
||
border: 1px solid var(--border-color, #e0e0e0);
|
||
}
|
||
|
||
#RelationsModal .badge {
|
||
font-size: 0.8rem;
|
||
padding: 4px 8px;
|
||
min-width: 42px;
|
||
}
|
||
|
||
#RelationsModal .badge.bg-syn {
|
||
background-color: #e91e63;
|
||
color: #ffffff;
|
||
}
|
||
|
||
#RelationsModal .relation-link {
|
||
color: var(--primary-color, #1a3a5c);
|
||
text-decoration: none;
|
||
cursor: pointer;
|
||
}
|
||
|
||
#RelationsModal .relation-link:hover {
|
||
text-decoration: underline;
|
||
color: var(--primary-light, #2a5a8c);
|
||
}
|
||
|
||
#RelationsModal .modal-body {
|
||
max-height: 75vh;
|
||
overflow-y: auto;
|
||
}
|
||
</style>
|
||
|
||
<script>
|
||
/**
|
||
* Relationen-Modal öffnen und Daten laden
|
||
*/
|
||
function ShowRelationsModal(id, authType) {
|
||
console.log('📋 Lade Relationen für ID:', id, 'Typ:', authType);
|
||
|
||
// Reset
|
||
$('#relations_modal_term').val('');
|
||
$('#relations_modal_id').val(id);
|
||
$('#relations_modal_descriptor').val('');
|
||
$('#relations_modal_body').html('');
|
||
$('#relations_modal_synonyms_body').html('');
|
||
$('#relations_modal_content').hide();
|
||
$('#relations_modal_empty').hide();
|
||
$('#relations_modal_synonyms').hide();
|
||
$('#relations_modal_loading').show();
|
||
$('#RelationsModalHeadline').html('<i class="fas fa-table"></i> Relationen');
|
||
|
||
// Modal öffnen
|
||
$('#RelationsModal').modal('show');
|
||
|
||
// Daten laden
|
||
$.get("/Thesaurus/ajax/getDetailAuthorityData.php", {
|
||
authType: authType,
|
||
offset: 0,
|
||
id: id,
|
||
sort: 'Anchor.Text',
|
||
limit: 1
|
||
}, function(data, status) {
|
||
if (status === "success") {
|
||
var metadata = (typeof data === 'string') ? JSON.parse(data) : data;
|
||
var row = metadata['rows'];
|
||
|
||
if (!row || row.length === 0) {
|
||
$('#relations_modal_loading').hide();
|
||
$('#relations_modal_empty').show();
|
||
return;
|
||
}
|
||
|
||
var entry = row[0];
|
||
|
||
// Info-Felder befüllen
|
||
$('#relations_modal_term').val(entry.Text || '');
|
||
$('#relations_modal_id').val(entry.ID || id);
|
||
$('#relations_modal_descriptor').val(entry.Descriptor === false ? 'Nein' : 'Ja');
|
||
|
||
// DSpace-Count laden (nur bei Subject/Person und Deskriptor)
|
||
var $dspaceField = $('#relations_modal_dspace');
|
||
$dspaceField.html('<span class="text-muted">–</span>');
|
||
|
||
if ((authType === 'Subject' || authType === 'Person') && entry.Descriptor !== false) {
|
||
$dspaceField.html('<span class="spinner-border spinner-border-sm text-muted" style="width: 12px; height: 12px;" role="status"></span>');
|
||
|
||
$.ajax({
|
||
url: '/Thesaurus/ajax/getDSpaceCount.php',
|
||
type: 'GET',
|
||
data: { authType: authType, query: entry.Text },
|
||
dataType: 'json',
|
||
timeout: 15000,
|
||
success: function(data) {
|
||
var count = (data && typeof data.count !== 'undefined') ? data.count : 0;
|
||
if (count === -1) {
|
||
$dspaceField.html('<span class="text-muted" title="DSpace nicht erreichbar"><i class="fas fa-exclamation-triangle"></i></span>');
|
||
} else if (count > 0) {
|
||
$dspaceField.html('<span class="badge" style="background-color: #1a3a5c;">' + count + ' Datensätze</span>');
|
||
} else {
|
||
$dspaceField.html('<span class="badge bg-danger">0</span>');
|
||
}
|
||
},
|
||
error: function() {
|
||
$dspaceField.html('<span class="text-muted"><i class="fas fa-exclamation-triangle"></i></span>');
|
||
}
|
||
});
|
||
}
|
||
|
||
// Badge-Konfiguration
|
||
var badgeConfig = {
|
||
'BT': { css: 'bg-success', title: 'BT - Oberbegriff' },
|
||
'NT': { css: 'bg-danger', title: 'NT - Unterbegriff' },
|
||
'RT': { css: 'bg-warning text-dark', title: 'RT - Verwandter Begriff' },
|
||
'USE': { css: 'bg-info', title: 'USE - Benutze' },
|
||
'UF': { css: 'bg-secondary', title: 'UF - Benutzt für' },
|
||
'USEDFOR': { css: 'bg-secondary', title: 'USEDFOR - Benutzt für' },
|
||
'FORMERNAME': { css: 'bg-success', title: 'Früherer Name' },
|
||
'LATERNAME': { css: 'bg-danger', title: 'Späterer Name' },
|
||
'USEDEARLIER': { css: 'bg-success', title: 'Früher verwendet' },
|
||
'USEDLATER': { css: 'bg-danger', title: 'Später verwendet' },
|
||
'ALTERNATIVENAME': { css: 'bg-warning text-dark', title: 'Alternativer Name' },
|
||
'SYN': { css: 'bg-syn', title: 'SYN - Synonym' }
|
||
};
|
||
|
||
// Relationen rendern
|
||
var relations = entry.Relations || [];
|
||
var html = '';
|
||
|
||
if (relations.length > 0) {
|
||
relations.forEach(function(rel) {
|
||
var relId = rel.IDRelation || '';
|
||
|
||
// Selbst-Relation überspringen
|
||
if (relId == id) return;
|
||
|
||
var relType = rel.Relationtype || 'RT';
|
||
var badge = badgeConfig[relType] || { css: 'bg-secondary', title: relType };
|
||
var relText = _escRelModal(rel.TextRelation || '');
|
||
var relId = rel.IDRelation || '';
|
||
|
||
html += '<tr>';
|
||
html += '<td><span class="badge ' + badge.css + '" title="' + badge.title + '">' + relType + '</span></td>';
|
||
html += '<td><a class="relation-link" href="javascript:void(0)" onclick="ShowRelationsModal(\'' + relId + '\', \'' + authType + '\')" title="Relationen anzeigen">' + relText + '</a></td>';
|
||
html += '<td class="text-center text-muted"><small>' + relId + '</small></td>';
|
||
html += '</tr>';
|
||
});
|
||
|
||
$('#relations_modal_body').html(html);
|
||
if (html.length > 0) {
|
||
$('#relations_modal_content').show();
|
||
} else {
|
||
$('#relations_modal_empty').show();
|
||
}
|
||
} else {
|
||
$('#relations_modal_empty').show();
|
||
}
|
||
|
||
// Synonyme (nur bei Subjects)
|
||
if (authType === 'Subject') {
|
||
var synonyms = entry.Synonyms || '';
|
||
|
||
// Falls leer, separat laden
|
||
if (!synonyms || synonyms.trim() === '') {
|
||
$.ajax({
|
||
url: "/Thesaurus/ajax/getSynonyms.php",
|
||
type: "GET",
|
||
data: { text: entry.Text },
|
||
dataType: "json",
|
||
success: function(synResponse) {
|
||
if (synResponse.success && synResponse.synonyms && synResponse.synonyms.length > 0) {
|
||
synonyms = synResponse.synonyms.map(function(s) { return s.text; }).join(', ');
|
||
_renderSynonymsInModal(synonyms, badgeConfig);
|
||
}
|
||
}
|
||
});
|
||
} else {
|
||
_renderSynonymsInModal(synonyms, badgeConfig);
|
||
}
|
||
}
|
||
|
||
$('#relations_modal_loading').hide();
|
||
}
|
||
}).fail(function() {
|
||
$('#relations_modal_loading').hide();
|
||
$('#relations_modal_empty').html('<i class="fas fa-exclamation-circle me-1 text-danger"></i> Fehler beim Laden der Relationen.').show();
|
||
});
|
||
}
|
||
|
||
function _renderSynonymsInModal(synonyms, badgeConfig) {
|
||
if (!synonyms || synonyms.trim() === '') return;
|
||
|
||
var synArray = synonyms.split(',').map(function(s) { return s.trim(); }).filter(function(s) { return s.length > 0; });
|
||
if (synArray.length === 0) return;
|
||
|
||
var badge = badgeConfig['SYN'];
|
||
var html = '';
|
||
|
||
synArray.forEach(function(synText) {
|
||
html += '<tr>';
|
||
html += '<td><span class="badge ' + badge.css + '" title="' + badge.title + '">SYN</span></td>';
|
||
html += '<td>' + _escRelModal(synText) + '</td>';
|
||
html += '</tr>';
|
||
});
|
||
|
||
$('#relations_modal_synonyms_body').html(html);
|
||
$('#relations_modal_synonyms').show();
|
||
}
|
||
|
||
function _escRelModal(text) {
|
||
if (!text) return '';
|
||
var div = document.createElement('div');
|
||
div.textContent = text;
|
||
return div.innerHTML;
|
||
}
|
||
|
||
/**
|
||
* Text in die Zwischenablage kopieren (modern mit Fallback)
|
||
*/
|
||
function copyTermToClipboard(text, btnElement) {
|
||
if (navigator.clipboard && navigator.clipboard.writeText) {
|
||
navigator.clipboard.writeText(text).then(function() {
|
||
_showCopyFeedback(btnElement);
|
||
}).catch(function() {
|
||
_fallbackCopy(text, btnElement);
|
||
});
|
||
} else {
|
||
_fallbackCopy(text, btnElement);
|
||
}
|
||
}
|
||
|
||
function _fallbackCopy(text, btnElement) {
|
||
var tempInput = document.createElement("input");
|
||
tempInput.value = text;
|
||
document.body.appendChild(tempInput);
|
||
tempInput.select();
|
||
document.execCommand("copy");
|
||
document.body.removeChild(tempInput);
|
||
_showCopyFeedback(btnElement);
|
||
}
|
||
|
||
function _showCopyFeedback(btnElement) {
|
||
if (!btnElement) return;
|
||
var $btn = $(btnElement).closest('.copy-btn');
|
||
var $icon = $btn.find('i');
|
||
$icon.removeClass('fa-copy').addClass('fa-check');
|
||
$btn.addClass('btn-success').removeClass('btn-outline-secondary');
|
||
setTimeout(function() {
|
||
$icon.removeClass('fa-check').addClass('fa-copy');
|
||
$btn.removeClass('btn-success').addClass('btn-outline-secondary');
|
||
}, 1500);
|
||
}
|
||
</script>
|
||
|