No tasks to display. Add tasks and calculate priorities.
';
tpc_disablePdfButton(type);
return;
}
const table = document.createElement('table');
table.className = 'tpc-results-table';
const thead = table.createTHead();
const tbody = table.createTBody();
const headerRow = thead.insertRow();
let headers = ['Priority', 'Task Name'];
if (type === 'eisenhower') headers.push('Category', 'Urgency', 'Importance', 'Due Date');
if (type === 'value-effort') headers.push('Category', 'Value', 'Effort', 'Due Date');
if (type === 'weighted-scoring') {
headers.push('Total Score');
if(criteriaDetails) criteriaDetails.forEach(c => headers.push(`${c.name} (Score)`));
headers.push('Due Date');
}
headers.forEach(text => {
const th = document.createElement('th');
th.textContent = text;
headerRow.appendChild(th);
});
tasks.forEach((task, index) => {
const row = tbody.insertRow();
row.insertCell().textContent = index + 1;
row.insertCell().textContent = task.name;
if (type === 'eisenhower') {
row.insertCell().textContent = task.category;
row.insertCell().textContent = task.urgency;
row.insertCell().textContent = task.importance;
row.classList.add(task.categoryClass);
} else if (type === 'value-effort') {
row.insertCell().textContent = task.category;
row.insertCell().textContent = task.value;
row.insertCell().textContent = task.effort;
row.classList.add(task.categoryClass);
} else if (type === 'weighted-scoring') {
row.insertCell().textContent = task.totalScore.toFixed(2);
if(criteriaDetails) {
criteriaDetails.forEach(criterion => {
row.insertCell().textContent = task.scores[criterion.id] || 'N/A';
});
}
}
row.insertCell().textContent = task.dueDate || 'N/A';
});
resultsArea.appendChild(table);
document.getElementById(`tpc-pdf-${type}`).disabled = false;
tpc_pdfData[type] = { tasks, headers, criteriaDetails, methodTitle: document.querySelector(`#tpc-${type} .tpc-section-title`).textContent };
}
function tpc_disablePdfButton(type) {
const pdfButton = document.getElementById(`tpc-pdf-${type}`);
if (pdfButton) pdfButton.disabled = true;
tpc_pdfData[type] = null;
}
function tpc_clearTasks(type) {
const taskList = document.getElementById(`tpc-${type}-tasks-list`);
if (taskList) taskList.innerHTML = '';
const resultsArea = document.getElementById(`tpc-${type}-results`);
if (resultsArea) resultsArea.innerHTML = '';
tpc_taskCounter[type] = 0;
if (type === 'weighted-scoring') {
const criteriaList = document.getElementById('tpc-criteria-list');
if (criteriaList) criteriaList.innerHTML = '';
tpc_criterionCounter = 0;
}
tpc_disablePdfButton(type);
}
function tpc_calculateEisenhower() {
let tasks = tpc_getTasks('eisenhower');
tasks.forEach(task => {
if (task.importance >= 4 && task.urgency >= 4) {
task.category = "Do First (Critical)"; task.priorityOrder = 1; task.categoryClass = "tpc-priority-critical";
} else if (task.importance >= 4 && task.urgency < 4) {
task.category = "Schedule (Important, Not Urgent)"; task.priorityOrder = 2; task.categoryClass = "tpc-priority-important-schedule";
} else if (task.importance < 4 && task.urgency >= 4) {
task.category = "Delegate (Urgent, Not Important)"; task.priorityOrder = 3; task.categoryClass = "tpc-priority-delegate";
} else {
task.category = "Eliminate (Not Urgent, Not Important)"; task.priorityOrder = 4; task.categoryClass = "tpc-priority-eliminate";
}
});
tasks.sort((a, b) => {
if (a.priorityOrder !== b.priorityOrder) return a.priorityOrder - b.priorityOrder;
if (a.urgency !== b.urgency) return b.urgency - a.urgency;
if (a.importance !== b.importance) return b.importance - a.importance;
if (a.dueDate && b.dueDate) return new Date(a.dueDate) - new Date(b.dueDate);
if (a.dueDate) return -1; if (b.dueDate) return 1;
return 0;
});
tpc_displayResults('eisenhower', tasks);
}
function tpc_calculateValueEffort() {
let tasks = tpc_getTasks('value-effort');
tasks.forEach(task => {
if (task.value >= 4 && task.effort <= 2) {
task.category = "Quick Wins (Do Now)"; task.priorityOrder = 1; task.categoryClass = "tpc-priority-quick-wins";
} else if (task.value >= 4 && task.effort >= 3) {
task.category = "Major Projects (Plan)"; task.priorityOrder = 2; task.categoryClass = "tpc-priority-major-projects";
} else if (task.value <= 3 && task.effort <= 2) {
task.category = "Fill-ins (Delegate or Do Later)"; task.priorityOrder = 3; task.categoryClass = "tpc-priority-fill-ins";
} else {
task.category = "Thankless Tasks (Avoid/Reconsider)"; task.priorityOrder = 4; task.categoryClass = "tpc-priority-avoid";
}
});
tasks.sort((a, b) => {
if (a.priorityOrder !== b.priorityOrder) return a.priorityOrder - b.priorityOrder;
if (a.value !== b.value) return b.value - a.value;
if (a.effort !== b.effort) return a.effort - b.effort;
if (a.dueDate && b.dueDate) return new Date(a.dueDate) - new Date(b.dueDate);
if (a.dueDate) return -1; if (b.dueDate) return 1;
return 0;
});
tpc_displayResults('value-effort', tasks);
}
function tpc_calculateWeighted() {
const criteria = tpc_getCriteria();
if (criteria.length === 0) {
alert("Please define criteria and their weights before calculating.");
return;
}
const totalWeightSum = criteria.reduce((sum, c) => sum + c.weight, 0);
if (totalWeightSum === 0 && criteria.some(c => c.weight !== 0)) {
alert("Total weight of criteria is zero. Please assign positive weights to at least one criterion.");
return;
}
let tasks = tpc_getTasks('weighted-scoring');
tasks.forEach(task => {
task.totalScore = 0;
if (totalWeightSum > 0) {
criteria.forEach(criterion => {
const score = task.scores[criterion.id] || 0;
const normalizedCriterionWeight = criterion.weight / totalWeightSum;
task.totalScore += score * normalizedCriterionWeight;
});
} else {
task.totalScore = 0;
}
});
tasks.sort((a, b) => {
if (b.totalScore !== a.totalScore) return b.totalScore - a.totalScore;
if (a.dueDate && b.dueDate) return new Date(a.dueDate) - new Date(b.dueDate);
if (a.dueDate) return -1; if (b.dueDate) return 1;
return 0;
});
tpc_displayResults('weighted-scoring', tasks, criteria);
}
function tpc_downloadPDF(type) {
if (!tpc_jsPDF_loaded) {
alert("TPC Error: jsPDF library is not loaded. Cannot generate PDF.");
return;
}
if (!tpc_autoTable_loaded) { // Check if autoTable became available after the timeout
const testDoc = new TPC_jsPDF();
if (typeof testDoc.autoTable === 'function') {
tpc_autoTable_loaded = true; // It loaded eventually
console.log("TPC: jsPDF-AutoTable confirmed loaded on demand.");
} else {
alert("TPC Error: jsPDF-AutoTable plugin is still not available. PDF table functionality will not work.");
return;
}
}
const data = tpc_pdfData[type];
if (!data || !data.tasks || data.tasks.length === 0) {
alert("No data to download. Please calculate priorities first.");
return;
}
const doc = new TPC_jsPDF();
const { tasks, headers, criteriaDetails, methodTitle } = data;
const primaryColor = getComputedStyle(document.documentElement).getPropertyValue('--primary-color').trim();
const darkColor = getComputedStyle(document.documentElement).getPropertyValue('--dark-color').trim();
doc.setFontSize(18);
doc.setTextColor(primaryColor);
doc.text("Task Priority Calculator Results", 14, 20);
doc.setFontSize(14);
doc.setTextColor(darkColor);
doc.text(`Method: ${methodTitle.split(':')[0]}`, 14, 30);
doc.setFontSize(10);
doc.text(`Date: ${new Date().toLocaleDateString()}`, 14, 36);
let tableHeaders = [];
let tableBody = [];
let startY = 45;
if (type === 'weighted-scoring' && criteriaDetails && criteriaDetails.length > 0) {
doc.setFontSize(12);
doc.text("Criteria & Normalized Weights:", 14, startY);
startY += 7;
let criteriaTableBody = [];
const totalActualWeight = criteriaDetails.reduce((sum, c) => sum + c.weight, 0);
criteriaDetails.forEach(c => {
criteriaTableBody.push([c.name, c.weight.toFixed(2), totalActualWeight > 0 ? ((c.weight / totalActualWeight) * 100).toFixed(2) + '%' : 'N/A']);
});
doc.autoTable({
startY: startY,
head: [['Criterion Name', 'Assigned Weight', 'Normalized Contribution']],
body: criteriaTableBody,
theme: 'grid',
headStyles: { fillColor: primaryColor, textColor: '#ffffff' },
styles: { fontSize: 9, cellPadding: 2 },
margin: { top: 10, bottom:10 }
});
startY = doc.lastAutoTable.finalY + 10;
}
if (type === 'eisenhower') {
tableHeaders = ['Priority', 'Task Name', 'Category', 'Urgency', 'Importance', 'Due Date'];
tableBody = tasks.map((task, index) => [
index + 1,
task.name,
task.category,
task.urgency,
task.importance,
task.dueDate || 'N/A'
]);
} else if (type === 'value-effort') {
tableHeaders = ['Priority', 'Task Name', 'Category', 'Value', 'Effort', 'Due Date'];
tableBody = tasks.map((task, index) => [
index + 1,
task.name,
task.category,
task.value,
task.effort,
task.dueDate || 'N/A'
]);
} else if (type === 'weighted-scoring') {
tableHeaders = ['Priority', 'Task Name', 'Total Score'];
if(criteriaDetails) criteriaDetails.forEach(c => tableHeaders.push(`${c.name} (Score)`));
tableHeaders.push('Due Date');
tableBody = tasks.map((task, index) => {
let row = [index + 1, task.name, task.totalScore.toFixed(2)];
if(criteriaDetails) {
criteriaDetails.forEach(criterion => {
row.push(task.scores[criterion.id] || '0');
});
}
row.push(task.dueDate || 'N/A');
return row;
});
}
doc.autoTable({
head: [tableHeaders],
body: tableBody,
startY: startY,
theme: 'grid',
headStyles: { fillColor: primaryColor, textColor: '#ffffff' },
styles: { fontSize: 9, cellPadding: 2 }
});
doc.save(`Task_Priorities_${type}_${new Date().toISOString().slice(0,10)}.pdf`);
}
document.addEventListener('DOMContentLoaded', () => {
let initialTabId = 'tpc-eisenhower'; // Default tab
let buttonToActivate = document.querySelector('.tpc-tab-button.tpc-active'); // Check HTML first
if (buttonToActivate) {
const onclickAttr = buttonToActivate.getAttribute('onclick');
// Safer extraction of tab ID
const match = onclickAttr ? onclickAttr.match(/tpc_openTab\(\s*event,\s*'([^']+)'\s*\)/) : null;
if (match && match[1]) {
initialTabId = match[1];
} else { // Fallback if parsing active button fails, use default and find its button
buttonToActivate = document.querySelector(`.tpc-tab-button[onclick*="'${initialTabId}'"]`);
}
} else { // If no .tpc-active class in HTML, find button for default tab
buttonToActivate = document.querySelector(`.tpc-tab-button[onclick*="'${initialTabId}'"]`);
}
if (buttonToActivate) {
// Ensure all other buttons are not active and all other tabs are hidden
document.querySelectorAll('.tpc-tab-button').forEach(btn => btn.classList.remove('tpc-active'));
document.querySelectorAll('.tpc-tab-content').forEach(content => {
content.style.display = 'none';
content.classList.remove('tpc-active');
});
// Then activate the determined initial tab
tpc_openTab({ currentTarget: buttonToActivate }, initialTabId);
} else {
console.warn("TPC: Could not find a button to activate for the initial tab.");
}
});