divan/DivanRazor/wwwroot/js/personwindow.js
Anas Rashid c97bb18c3a Urdu public pages, batch 3 (#2): browser JS messages and labels
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 00:23:00 +02:00

140 lines
6.4 KiB
JavaScript
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.

// Generic inline-modal shell, loaded on every page (see _Layout.cshtml / _AdminLayout.cshtml),
// used to replace what used to be four standalone pages: Person.cshtml (a person's profile),
// People.cshtml (family-tree-roots index), PeopleGraph.cshtml (whole-site relationship graph) and
// FamilyTree.cshtml (one person's family-tree chart). Those pages had no independent purpose of
// their own - they only ever existed to show data reachable from somewhere else (a poem's tagged
// persons, a category's "شخصیت‌ها" tab, an admin moderation queue) - so instead of navigating
// away, callers open one of these three windows over whatever page they're already on:
//
// PersonWindow.open(id) - a small modal: one person's bio/relations/affiliations/poems,
// fetched from /PersonWindow/{id} (Person.cshtml's old content,
// stripped of site chrome - see PersonWindow.cshtml).
// PeopleExplorer.open() - a large modal: the whole-site force-directed graph (formerly
// /PeopleGraph) plus the family-tree-roots list (formerly /People),
// merged into one fragment fetched from /PeopleExplorer.
// FamilyTreeWindow.open(id) - a large modal: one person's connected-kinship-component tree
// chart (formerly /FamilyTree/{id}), fetched from
// /FamilyTreeWindow/{id} - see FamilyTreeWindow.cshtml.
//
// All three render into the same reusable overlay/modal shell built here on first use.
(function () {
'use strict';
var STYLE_ID = 'up-modal-styles';
var overlay, modal, body, closeBtn;
function ensureStyles() {
if (document.getElementById(STYLE_ID)) return;
var style = document.createElement('style');
style.id = STYLE_ID;
style.textContent =
'.up-modal-overlay{position:fixed;inset:0;background:rgba(30,20,10,.55);z-index:9000;' +
'display:none;align-items:flex-start;justify-content:center;overflow-y:auto;padding:5vh 16px;}' +
'.up-modal-overlay--open{display:flex;}' +
'.up-modal{position:relative;background:#fffdf7;border-radius:10px;box-shadow:0 8px 30px rgba(0,0,0,.35);' +
'padding:20px 24px;max-width:640px;width:100%;max-height:90vh;overflow-y:auto;direction:rtl;text-align:right;}' +
'.up-modal--lg{max-width:900px;}' +
'.up-modal-close{position:absolute;left:12px;top:10px;border:none;background:none;font-size:22px;' +
'line-height:1;cursor:pointer;color:#7a4a2a;}' +
'.up-modal-loading{text-align:center;padding:30px 0;}' +
'body.up-modal-noscroll{overflow:hidden;}';
document.head.appendChild(style);
}
function ensureShell() {
if (overlay) return;
ensureStyles();
overlay = document.createElement('div');
overlay.id = 'up-modal-overlay';
overlay.className = 'up-modal-overlay';
overlay.innerHTML =
'<div class="up-modal" id="up-modal">' +
'<button type="button" class="up-modal-close" id="up-modal-close" aria-label="بند کریں">×</button>' +
'<div class="up-modal-body" id="up-modal-body"></div>' +
'</div>';
document.body.appendChild(overlay);
modal = document.getElementById('up-modal');
body = document.getElementById('up-modal-body');
closeBtn = document.getElementById('up-modal-close');
closeBtn.addEventListener('click', closeModal);
overlay.addEventListener('click', function (evt) {
if (evt.target === overlay) closeModal();
});
document.addEventListener('keydown', function (evt) {
if (evt.key === 'Escape' && overlay.classList.contains('up-modal-overlay--open')) {
closeModal();
}
});
}
function openModal(large) {
ensureShell();
modal.classList.toggle('up-modal--lg', !!large);
body.innerHTML = '<div class="up-modal-loading"><img src="/image/loading.gif" alt="لوڈ کریں" /></div>';
overlay.classList.add('up-modal-overlay--open');
document.body.classList.add('up-modal-noscroll');
}
function closeModal() {
if (!overlay) return;
overlay.classList.remove('up-modal-overlay--open');
document.body.classList.remove('up-modal-noscroll');
}
function loadInto(url, onReady) {
$.ajax({
type: 'GET',
url: url,
error: function () {
if (body) body.innerHTML = '<p>معلومات لوڈ کرنے میں خرابی.</p>';
},
success: function (data) {
body.innerHTML = data;
if (onReady) onReady();
}
});
}
function openPerson(id) {
openModal(false);
loadInto('/PersonWindow/' + String(id));
}
function openExplorer() {
openModal(true);
loadInto('/PeopleExplorer', function () {
var dataEl = document.getElementById('pge-data');
if (dataEl && window.DivanPeopleGraph) {
var graphData = JSON.parse(dataEl.textContent);
DivanPeopleGraph.render({
containerId: 'pge-container',
svgId: 'pge-svg',
tableBodyId: 'pge-table-body',
legendId: 'pge-legend',
searchInputId: 'pge-search',
resetButtonId: 'pge-reset',
data: graphData
});
}
});
}
function openFamilyTree(id) {
openModal(true);
loadInto('/FamilyTreeWindow/' + String(id), function () {
var dataEl = document.getElementById('ftw-data');
var rootIdEl = document.getElementById('ftw-root-id');
if (dataEl && rootIdEl && window.DivanFamilyTree) {
var treeData = JSON.parse(dataEl.textContent);
var rootId = parseInt(rootIdEl.value, 10);
DivanFamilyTree.render('familytree-container', 'familytree-svg', 'familytree-tooltip', treeData, rootId);
}
});
}
window.PersonWindow = { open: openPerson, close: closeModal };
window.PeopleExplorer = { open: openExplorer, close: closeModal };
window.FamilyTreeWindow = { open: openFamilyTree, close: closeModal };
})();