fix(i18n): complete architecture page translations and fix diagram modals
- Added data-i18n to service card descriptions (validator, pressure, metacognitive, deliberation) - Fixed interactive-diagram.js to properly load translations from i18n system - Added language change handlers for dynamic modal updates - All service cards and modals now fully translate across EN/DE/FR
This commit is contained in:
parent
8b3b37bdee
commit
5643050eb6
2 changed files with 114 additions and 50 deletions
|
|
@ -251,7 +251,7 @@
|
|||
<h3 class="text-lg font-bold text-gray-900 break-words overflow-wrap-anywhere" data-i18n="services.validator.name"></h3>
|
||||
</div>
|
||||
<p class="text-gray-600 text-sm mb-3 break-words overflow-wrap-anywhere">
|
||||
Validates AI actions against instruction history. Aims to prevent pattern bias overriding explicit directives.
|
||||
<span data-i18n="services.validator.description"></span>
|
||||
</p>
|
||||
<div class="text-xs rounded px-3 py-2" class="badge-validator" data-i18n-html="services.validator.promise">
|
||||
<strong>Early Promise:</strong> Independent verification—AI claims checked against external source.
|
||||
|
|
@ -268,7 +268,7 @@
|
|||
<h3 class="text-lg font-bold text-gray-900 break-words overflow-wrap-anywhere" data-i18n="services.pressure.name"></h3>
|
||||
</div>
|
||||
<p class="text-gray-600 text-sm mb-3 break-words overflow-wrap-anywhere">
|
||||
Monitors AI performance degradation. Escalates when context pressure threatens quality.
|
||||
<span data-i18n="services.pressure.description"></span>
|
||||
</p>
|
||||
<div class="text-xs rounded px-3 py-2" class="badge-pressure" data-i18n-html="services.pressure.promise">
|
||||
<strong>Early Promise:</strong> Objective metrics may detect manipulation attempts early.
|
||||
|
|
@ -285,7 +285,7 @@
|
|||
<h3 class="text-lg font-bold text-gray-900 break-words overflow-wrap-anywhere" data-i18n="services.metacognitive.name"></h3>
|
||||
</div>
|
||||
<p class="text-gray-600 text-sm mb-3 break-words overflow-wrap-anywhere">
|
||||
Requires AI to pause and verify complex operations before execution. Structural safety check.
|
||||
<span data-i18n="services.metacognitive.description"></span>
|
||||
</p>
|
||||
<div class="text-xs rounded px-3 py-2" class="badge-metacognitive" data-i18n-html="services.metacognitive.promise">
|
||||
<strong>Early Promise:</strong> Architectural gates aim to enforce verification steps.
|
||||
|
|
@ -302,7 +302,7 @@
|
|||
<h3 class="text-lg font-bold text-gray-900 break-words overflow-wrap-anywhere" data-i18n="services.deliberation.name"></h3>
|
||||
</div>
|
||||
<p class="text-gray-600 text-sm mb-3 break-words overflow-wrap-anywhere">
|
||||
Facilitates multi-stakeholder deliberation for values conflicts. AI provides facilitation, not authority.
|
||||
<span data-i18n="services.deliberation.description"></span>
|
||||
</p>
|
||||
<div class="text-xs rounded px-3 py-2" class="badge-deliberation" data-i18n-html="services.deliberation.promise">
|
||||
<strong>Early Promise:</strong> Human judgment required—architecturally enforced escalation for values.
|
||||
|
|
|
|||
|
|
@ -57,6 +57,116 @@ class InteractiveDiagram {
|
|||
console.log('[InteractiveDiagram] Loaded translations for', Object.keys(this.serviceData).length, 'services');
|
||||
}
|
||||
|
||||
handleLanguageChange() {
|
||||
console.log('[InteractiveDiagram] Language changed, reloading translations');
|
||||
this.loadTranslations();
|
||||
// Re-render current service if one is active
|
||||
if (this.activeService) {
|
||||
const service = this.serviceData[this.activeService];
|
||||
if (service) {
|
||||
this.renderServicePanel(service);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
init() {
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', () => this.setup());
|
||||
} else {
|
||||
this.setup();
|
||||
}
|
||||
|
||||
console.log('[InteractiveDiagram] Initialized');
|
||||
}
|
||||
|
||||
setup() {
|
||||
// SVG is loaded via <object> tag, need to access its contentDocument
|
||||
const objectElement = document.getElementById('interactive-svg-object');
|
||||
if (!objectElement) {
|
||||
console.warn('[InteractiveDiagram] SVG object element not found');
|
||||
return;
|
||||
}
|
||||
|
||||
// Wait for object to load with retry mechanism
|
||||
const initializeSVG = () => {
|
||||
const svgDoc = objectElement.contentDocument;
|
||||
if (!svgDoc) {
|
||||
console.warn('[InteractiveDiagram] Could not access SVG contentDocument, retrying...');
|
||||
setTimeout(initializeSVG, 100);
|
||||
return;
|
||||
}
|
||||
|
||||
// The SVG is the document element itself, or we can query for it
|
||||
let svg = svgDoc.getElementById('interactive-arch-diagram');
|
||||
if (!svg) {
|
||||
// Try getting the root SVG element
|
||||
svg = svgDoc.documentElement;
|
||||
console.log('[InteractiveDiagram] Using documentElement as SVG');
|
||||
}
|
||||
|
||||
if (!svg) {
|
||||
console.warn('[InteractiveDiagram] SVG diagram not found in contentDocument');
|
||||
return;
|
||||
}
|
||||
|
||||
// Verify it's actually an SVG element (case-insensitive check)
|
||||
const tagName = svg.tagName ? svg.tagName.toLowerCase() : '';
|
||||
if (tagName !== 'svg') {
|
||||
console.warn('[InteractiveDiagram] Element found but not SVG, tagName:', tagName, '- retrying...');
|
||||
// This is the race condition - contentDocument is HTML, not SVG yet
|
||||
setTimeout(initializeSVG, 100);
|
||||
return;
|
||||
}
|
||||
|
||||
// Store reference to SVG document for later use
|
||||
this.svgDoc = svgDoc;
|
||||
this.svg = svg;
|
||||
|
||||
const nodes = svg.querySelectorAll('.service-node');
|
||||
console.log(`[InteractiveDiagram] Found ${nodes.length} service nodes`);
|
||||
|
||||
if (nodes.length === 0) {
|
||||
console.warn('[InteractiveDiagram] No service nodes found in SVG');
|
||||
return;
|
||||
}
|
||||
|
||||
nodes.forEach(node => {
|
||||
const serviceId = node.getAttribute('data-service');
|
||||
|
||||
// Click handler
|
||||
node.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
this.showServiceDetails(serviceId);
|
||||
}, true);
|
||||
|
||||
// Touch support for mobile devices
|
||||
node.addEventListener('touchstart', (e) => {
|
||||
e.preventDefault();
|
||||
const serviceId = node.getAttribute('data-service');
|
||||
this.showServiceDetails(serviceId);
|
||||
}, { passive: false });
|
||||
|
||||
// Hover effects
|
||||
node.addEventListener('mouseenter', () => {
|
||||
this.highlightService(serviceId);
|
||||
});
|
||||
|
||||
node.addEventListener('mouseleave', () => {
|
||||
this.unhighlightService(serviceId);
|
||||
});
|
||||
|
||||
// Add pointer cursor via JavaScript (CSP-compliant)
|
||||
node.style.cursor = 'pointer';
|
||||
});
|
||||
|
||||
this.addKeyboardNavigation(nodes);
|
||||
|
||||
// Show initial state (overview)
|
||||
this.showServiceDetails('overview');
|
||||
console.log('[InteractiveDiagram] Setup complete, showing overview');
|
||||
};
|
||||
|
||||
// FIXED: Better load detection with SVG verification
|
||||
const checkAndInit = () => {
|
||||
const svgDoc = objectElement.contentDocument;
|
||||
|
|
@ -263,52 +373,6 @@ class InteractiveDiagram {
|
|||
}
|
||||
}
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
window.interactiveDiagram = new InteractiveDiagram();
|
||||
}
|
||||
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
module.exports = InteractiveDiagram;
|
||||
}
|
||||
|
||||
// Listen for language changes and reload translations
|
||||
handleLanguageChange() {
|
||||
console.log('[InteractiveDiagram] Language changed, reloading translations');
|
||||
this.loadTranslations();
|
||||
// Re-render current service if one is active
|
||||
if (this.activeService) {
|
||||
const service = this.serviceData[this.activeService];
|
||||
if (service) {
|
||||
this.renderServicePanel(service);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize and listen for language changes
|
||||
if (typeof window !== 'undefined') {
|
||||
window.interactiveDiagram = new InteractiveDiagram();
|
||||
|
||||
// Listen for i18n initialization and language changes
|
||||
window.addEventListener('i18nInitialized', () => {
|
||||
if (window.interactiveDiagram) {
|
||||
window.interactiveDiagram.handleLanguageChange();
|
||||
|
||||
// Listen for language changes and reload translations
|
||||
handleLanguageChange() {
|
||||
console.log('[InteractiveDiagram] Language changed, reloading translations');
|
||||
this.loadTranslations();
|
||||
// Re-render current service if one is active
|
||||
if (this.activeService) {
|
||||
const service = this.serviceData[this.activeService];
|
||||
if (service) {
|
||||
this.renderServicePanel(service);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize and listen for language changes
|
||||
if (typeof window !== 'undefined') {
|
||||
window.interactiveDiagram = new InteractiveDiagram();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue