This commit is contained in:
centron\schwoerer
2025-11-18 16:35:03 +01:00
parent 167cd0e02d
commit 33aebf2b87

View File

@@ -1,5 +1,6 @@
const MODULE_ID = "gowlers-tracking-ledger"; const MODULE_ID = "gowlers-tracking-ledger";
const MODULE_VERSION = "0.1.0";
const TRACK_SETTING = "actorSettings"; const TRACK_SETTING = "actorSettings";
const FLAG_SCOPE = "world"; const FLAG_SCOPE = "world";
const MAX_HISTORY_ROWS = 100; const MAX_HISTORY_ROWS = 100;
@@ -291,112 +292,92 @@ function openHistoryDialog(actor, initialTab = "hp") {
if (!actor) return; if (!actor) return;
const content = buildHistoryContent(actor, initialTab); const content = buildHistoryContent(actor, initialTab);
// Create a custom dialog with header button
const dialog = new Dialog( const dialog = new Dialog(
{ {
title: `${actor.name}: Log`, title: `${actor.name}: Tracking Log`,
content, content,
buttons: { close: { label: "Close" } }, buttons: { close: { label: "Close" } },
}, },
{ {
width: 720, width: 800,
height: "auto",
classes: ["pf1-history-dialog"], classes: ["pf1-history-dialog"],
render: (html) => { render: (html) => {
// html is jQuery object of the dialog element // Use jQuery for robust event delegation
// Find the content root within the dialog const $html = $(html);
const root = html.find('[data-history-root]')[0]; const $root = $html.find('[data-history-root]');
if (!root) {
console.warn("[History Dialog] Root element not found");
return;
}
console.log("[History Dialog] Root element found, setting up tabs"); if (!$root.length) return;
// Get all tab buttons and panels // Tab switching with jQuery delegation
const buttons = Array.from(root.querySelectorAll('.history-tab-link')); $root.on('click', '[data-history-tab]', function(e) {
const panels = Array.from(root.querySelectorAll('.history-panel')); e.preventDefault();
const tabId = $(this).data('history-tab');
console.log(`[History Dialog] Found ${buttons.length} tabs and ${panels.length} panels`); // Update tab buttons
$root.find('[data-history-tab]').removeClass('active');
$root.find(`[data-history-tab="${tabId}"]`).addClass('active');
// Tab activation function // Update panels
const activateTab = (tabId) => { $root.find('[data-history-panel]').hide();
console.log(`[History Dialog] Activating tab: ${tabId}`); $root.find(`[data-history-panel="${tabId}"]`).show();
buttons.forEach((btn) => {
const shouldBeActive = btn.dataset.historyTab === tabId;
btn.classList.toggle('active', shouldBeActive);
});
panels.forEach((panel) => {
const shouldBeActive = panel.dataset.historyPanel === tabId;
panel.style.display = shouldBeActive ? 'block' : 'none';
panel.classList.toggle('active', shouldBeActive);
});
};
// Bind tab click handlers using event delegation
buttons.forEach((btn, index) => {
btn.style.cursor = 'pointer';
btn.addEventListener('click', function(event) {
event.preventDefault();
event.stopPropagation();
const tabId = this.dataset.historyTab;
console.log(`[History Dialog] Tab clicked: ${tabId}`);
activateTab(tabId);
return false;
});
}); });
// Bind config button in content // Config button handler
const configBtn = root.querySelector('[data-action="open-config"]'); $root.on('click', '[data-action="open-config"]', function(e) {
if (configBtn) { e.preventDefault();
configBtn.addEventListener('click', (event) => { const api = window.GowlersTrackingLedger;
event.preventDefault(); if (api?.openConfigForActor) {
event.stopPropagation(); api.openConfigForActor(actor.id);
console.log("[History Dialog] Config button clicked (content)"); } else if (api?.openConfig) {
const api = window.GowlersTrackingLedger; api.openConfig();
if (api?.openConfigForActor) { }
api.openConfigForActor(actor.id); });
} else if (api?.openConfig) {
api.openConfig();
}
});
}
// Add config button to dialog header if user is GM // Add config icon to dialog header (GM only)
if (game.user?.isGM) { if (game.user?.isGM) {
const header = html.find('.dialog-header')[0]; const $header = $html.find('.dialog-header');
if (header) { if ($header.length && !$header.find('[data-history-config-header]').length) {
const existingBtn = header.querySelector('[data-history-config-header]'); const $configBtn = $('<button/>', {
if (!existingBtn) { type: 'button',
const configHeaderBtn = document.createElement('button'); class: 'history-config-header-btn',
configHeaderBtn.type = 'button'; 'data-history-config-header': 'true',
configHeaderBtn.className = 'history-config-header-btn'; title: 'Configure Actor Tracking',
configHeaderBtn.setAttribute('data-history-config-header', 'true'); html: '<i class="fas fa-cog"></i>',
configHeaderBtn.setAttribute('title', 'Configure Actor Tracking'); css: {
configHeaderBtn.innerHTML = '<i class="fas fa-cog" style="font-size: 18px;"></i>'; border: 'none',
configHeaderBtn.style.cssText = 'border: none; background: transparent; color: #666; cursor: pointer; padding: 8px 10px; margin-right: 8px; transition: color 0.2s;'; background: 'transparent',
configHeaderBtn.addEventListener('mouseover', () => configHeaderBtn.style.color = '#333'); color: '#999',
configHeaderBtn.addEventListener('mouseout', () => configHeaderBtn.style.color = '#666'); cursor: 'pointer',
configHeaderBtn.addEventListener('click', (event) => { padding: '4px 8px',
event.preventDefault(); marginRight: '4px',
event.stopPropagation(); fontSize: '18px',
console.log("[History Dialog] Config button clicked (header)"); transition: 'color 0.2s'
const api = window.GowlersTrackingLedger;
if (api?.openConfigForActor) {
api.openConfigForActor(actor.id);
} else if (api?.openConfig) {
api.openConfig();
}
});
const closeBtn = header.querySelector('.close');
if (closeBtn) {
header.insertBefore(configHeaderBtn, closeBtn);
} else {
header.appendChild(configHeaderBtn);
} }
console.log("[History Dialog] Config header button added"); });
}
$configBtn.hover(
function() { $(this).css('color', '#333'); },
function() { $(this).css('color', '#999'); }
);
$configBtn.click(function(e) {
e.preventDefault();
const api = window.GowlersTrackingLedger;
if (api?.openConfigForActor) {
api.openConfigForActor(actor.id);
} else if (api?.openConfig) {
api.openConfig();
}
});
$header.find('.close').before($configBtn);
} }
} }
// Set initial tab
$root.find(`[data-history-tab="${initialTab}"]`).addClass('active');
$root.find(`[data-history-panel="${initialTab}"]`).show();
}, },
} }
); );
@@ -474,14 +455,6 @@ function buildHistoryContent(actor, initialTab = "hp") {
}) })
.join(""); .join("");
const toolbar = canConfigure
? `<div class="history-dialog-toolbar">
<button type="button" class="history-config-btn" data-action="open-config">
<i class="fas fa-sliders-h"></i> Configure Actor
</button>
</div>`
: "";
return ` return `
<section class="history-dialog-root" data-history-root="${actor.id}"> <section class="history-dialog-root" data-history-root="${actor.id}">
<style> <style>
@@ -490,17 +463,18 @@ function buildHistoryContent(actor, initialTab = "hp") {
.history-dialog-tabs .item:not(.active) { opacity:0.75; } .history-dialog-tabs .item:not(.active) { opacity:0.75; }
.history-dialog-tabs .item:first-child { border-top-left-radius:6px; } .history-dialog-tabs .item:first-child { border-top-left-radius:6px; }
.history-dialog-tabs .item:last-child { border-top-right-radius:6px; } .history-dialog-tabs .item:last-child { border-top-right-radius:6px; }
.history-dialog-tabs .item.active { background:#fff; opacity:1; position:relative; top:1px; } .history-dialog-tabs .item.active { background:#fff; opacity:1; position:relative; top:1px; cursor:pointer; }
.history-dialog-panels { border:1px solid #b5b3a4; border-top:none; padding:8px; border-radius:0 6px 6px 6px; background:#fff; } .history-dialog-panels { border:1px solid #b5b3a4; border-top:none; padding:8px; border-radius:0 6px 6px 6px; background:#fff; min-height: 200px; }
.history-table { width:100%; border-collapse:collapse; } .history-table { width:100%; border-collapse:collapse; }
.history-table th, .history-table td { border:1px solid #b5b3a4; padding:4px; text-align:left; } .history-table th, .history-table td { border:1px solid #b5b3a4; padding:4px; text-align:left; }
.history-empty { font-style:italic; } .history-empty { font-style:italic; color: #999; }
.history-dialog-toolbar { display:flex; justify-content:flex-end; margin-bottom:6px; gap:8px; } .history-dialog-footer { font-size: 0.8em; color: #999; text-align: center; margin-top: 8px; padding-top: 8px; border-top: 1px solid #e0e0e0; }
.history-config-btn { border:1px solid #b5b3a4; background:#d6d3c8; border-radius:4px; padding:4px 8px; font-size:0.85em; cursor:pointer; }
</style> </style>
${toolbar}
<nav class="history-dialog-tabs">${tabs}</nav> <nav class="history-dialog-tabs">${tabs}</nav>
<div class="history-dialog-panels">${panels}</div> <div class="history-dialog-panels">${panels}</div>
<div class="history-dialog-footer">
Gowler's Tracking Ledger v${MODULE_VERSION}
</div>
</section>`; </section>`;
} }