Goal Dashboard

Manage Goal & Key Results

Please select a goal from the dropdown above or add a new goal from the Dashboard.

Archived Goals (Achieved or Cancelled)

Target Date: ${goal.targetDate ? new Date(goal.targetDate+"T00:00:00").toLocaleDateString() : 'Not set'}

Progress: ${progress}%

`; dashboardArea.appendChild(card); }); } function wgt_initAddNewGoal() { wgt_currentGoalIdForManagement = null; // Clear any selected goal // Reset form fields on manage tab for a new goal document.getElementById('wgt-goalDetailForm').reset(); document.getElementById('wgt-detailGoalId').value = ''; document.getElementById('wgt-detailGoalColor').value = `#${Math.floor(Math.random()*16777215).toString(16).padStart(6,'0')}`; // Random color const nextMonth = new Date(WGT_TODAY_CONTEXT); nextMonth.setMonth(nextMonth.getMonth()+1); nextMonth.setDate(new Date(nextMonth.getFullYear(), nextMonth.getMonth() + 1, 0).getDate()); // End of next month document.getElementById('wgt-detailTargetDate').value = nextMonth.toISOString().split('T')[0]; document.getElementById('wgt-detailGoalStatus').value = "Not Started"; document.getElementById('wgt-detailGoalPriority').value = "Medium"; document.getElementById('wgt-keyResultsList').innerHTML = '
  • Save the goal first to add key results.
  • '; document.getElementById('wgt-goalReflectionNotes').value = ''; document.getElementById('wgt-krGoalName').textContent = "New Goal"; document.getElementById('wgt-reflectGoalName').textContent = "New Goal"; // Switch to manage tab const manageTabButton = document.querySelector(`.wgt-tab-button[onclick*="'wgt-manageGoalTab'"]`); wgt_openTab({currentTarget: manageTabButton}, 'wgt-manageGoalTab'); document.getElementById('wgt-goalManagementArea').style.display = 'block'; document.getElementById('wgt-noGoalSelectedMessage').style.display = 'none'; document.getElementById('wgt-selectGoalToManage').value = ""; // Ensure dropdown is cleared } // --- Manage Goal & Key Results Tab --- function wgt_initManageGoalTab() { wgt_populateGoalSelectForManagement(); if (wgt_currentGoalIdForManagement) { wgt_loadGoalForManagement(wgt_currentGoalIdForManagement); } else { document.getElementById('wgt-goalManagementArea').style.display = 'none'; document.getElementById('wgt-noGoalSelectedMessage').style.display = 'block'; } } function wgt_populateGoalSelectForManagement() { const selectEl = document.getElementById('wgt-selectGoalToManage'); const activeGoals = wgt_goals.filter(g => g.status !== 'Achieved' && g.status !== 'Cancelled'); selectEl.innerHTML = ''; activeGoals.forEach(goal => { const option = document.createElement('option'); option.value = goal.id; option.textContent = goal.name; selectEl.appendChild(option); }); if (wgt_currentGoalIdForManagement && activeGoals.find(g => g.id === wgt_currentGoalIdForManagement)) { selectEl.value = wgt_currentGoalIdForManagement; } else if (activeGoals.length > 0 && !wgt_currentGoalIdForManagement) { // If no goal was selected, but there are active goals, don't auto-select, let user choose. // wgt_loadGoalForManagement(activeGoals[0].id); // Optionally auto-load first } } function wgt_loadGoalForManagement(goalId, switchToTab = false) { if (!goalId) { wgt_currentGoalIdForManagement = null; document.getElementById('wgt-goalManagementArea').style.display = 'none'; document.getElementById('wgt-noGoalSelectedMessage').style.display = 'block'; return; } wgt_currentGoalIdForManagement = goalId; const goal = wgt_goals.find(g => g.id === goalId); if (!goal) { wgt_currentGoalIdForManagement = null; // Clear if goal not found document.getElementById('wgt-goalManagementArea').style.display = 'none'; document.getElementById('wgt-noGoalSelectedMessage').style.display = 'block'; alert("Selected goal not found."); return; } document.getElementById('wgt-detailGoalId').value = goal.id; document.getElementById('wgt-detailGoalName').value = goal.name; document.getElementById('wgt-detailGoalDescription').value = goal.description || ''; document.getElementById('wgt-detailTargetDate').value = goal.targetDate || ''; document.getElementById('wgt-detailGoalStatus').value = goal.status || 'Not Started'; document.getElementById('wgt-detailGoalPriority').value = goal.priority || 'Medium'; document.getElementById('wgt-detailGoalColor').value = goal.color || '#10B981'; document.getElementById('wgt-goalReflectionNotes').value = goal.reflectionNotes || ''; document.getElementById('wgt-krGoalName').textContent = goal.name; document.getElementById('wgt-reflectGoalName').textContent = goal.name; wgt_renderKeyResultsList(goalId); wgt_resetKeyResultForm(); // Clear KR form for new entry document.getElementById('wgt-goalManagementArea').style.display = 'block'; document.getElementById('wgt-noGoalSelectedMessage').style.display = 'none'; document.getElementById('wgt-selectGoalToManage').value = goalId; if (switchToTab) { const manageTabButton = document.querySelector(`.wgt-tab-button[onclick*="'wgt-manageGoalTab'"]`); wgt_openTab({currentTarget: manageTabButton}, 'wgt-manageGoalTab'); } } document.getElementById('wgt-goalDetailForm').onsubmit = (e) => { e.preventDefault(); const goalId = document.getElementById('wgt-detailGoalId').value; if (!goalId) { // This means it's a new goal being created via "Add New Goal" button flow const newGoal = { id: wgt_generateId(), name: document.getElementById('wgt-detailGoalName').value.trim(), description: document.getElementById('wgt-detailGoalDescription').value.trim(), targetDate: document.getElementById('wgt-detailTargetDate').value, status: document.getElementById('wgt-detailGoalStatus').value, priority: document.getElementById('wgt-detailGoalPriority').value, color: document.getElementById('wgt-detailGoalColor').value, keyResults: [], reflectionNotes: '' }; if (!newGoal.name) { alert("Goal name is required."); return; } wgt_goals.push(newGoal); wgt_currentGoalIdForManagement = newGoal.id; // Set current to this new goal } else { // Editing existing goal const goalIndex = wgt_goals.findIndex(g => g.id === goalId); if (goalIndex === -1) { alert("Goal not found for update."); return; } wgt_goals[goalIndex].name = document.getElementById('wgt-detailGoalName').value.trim(); wgt_goals[goalIndex].description = document.getElementById('wgt-detailGoalDescription').value.trim(); wgt_goals[goalIndex].targetDate = document.getElementById('wgt-detailTargetDate').value; wgt_goals[goalIndex].status = document.getElementById('wgt-detailGoalStatus').value; wgt_goals[goalIndex].priority = document.getElementById('wgt-detailGoalPriority').value; wgt_goals[goalIndex].color = document.getElementById('wgt-detailGoalColor').value; } wgt_saveData(); alert("Goal details saved!"); wgt_renderGoalDashboard(); // Update dashboard if name/status changed wgt_populateGoalSelectForManagement(); // Refresh dropdown document.getElementById('wgt-selectGoalToManage').value = wgt_currentGoalIdForManagement; // Re-select current goal wgt_loadGoalForManagement(wgt_currentGoalIdForManagement); // Reload to reflect changes and KR list for current goal }; // Key Results Management document.getElementById('wgt-keyResultForm').onsubmit = (e) => { e.preventDefault(); if (!wgt_currentGoalIdForManagement) { alert("No goal selected to add key result to."); return; } const goalIndex = wgt_goals.findIndex(g => g.id === wgt_currentGoalIdForManagement); if (goalIndex === -1) { alert("Selected goal not found."); return; } const krId = document.getElementById('wgt-keyResultId').value; const krData = { id: krId || wgt_generateId(), description: document.getElementById('wgt-krDescription').value.trim(), dueDate: document.getElementById('wgt-krDueDate').value || null, isDone: document.getElementById('wgt-krIsDone').checked }; if (!krData.description) { alert("Key result description is required."); return; } if (!wgt_goals[goalIndex].keyResults) wgt_goals[goalIndex].keyResults = []; if (krId) { // Editing KR const krIndex = wgt_goals[goalIndex].keyResults.findIndex(kr => kr.id === krId); if (krIndex > -1) wgt_goals[goalIndex].keyResults[krIndex] = krData; } else { // Adding new KR wgt_goals[goalIndex].keyResults.push(krData); } wgt_saveData(); wgt_renderKeyResultsList(wgt_currentGoalIdForManagement); wgt_resetKeyResultForm(); wgt_renderGoalDashboard(); // Update progress on dashboard }; function wgt_resetKeyResultForm() {document.getElementById('wgt-keyResultForm').reset(); document.getElementById('wgt-keyResultId').value=''; document.getElementById('wgt-krIsDone').checked=false; document.getElementById('wgt-cancelKrEditBtn').style.display='none';} function wgt_renderKeyResultsList(goalId) { const listEl = document.getElementById('wgt-keyResultsList'); const goal = wgt_goals.find(g => g.id === goalId); listEl.innerHTML = ''; if (!goal || !goal.keyResults || goal.keyResults.length === 0) { listEl.innerHTML = '
  • No key results defined for this goal yet.
  • '; return; } goal.keyResults.sort((a,b) => (a.dueDate || '9999-12-31') > (b.dueDate || '9999-12-31') ? 1 : -1).forEach(kr => { const li = document.createElement('li'); li.className = `wgt-keyresult-item ${kr.isDone ? 'done' : ''}`; li.innerHTML = ` ${kr.description} ${kr.dueDate ? new Date(kr.dueDate+"T00:00:00").toLocaleDateString() : 'No due date'}
    `; listEl.appendChild(li); }); } function wgt_editKeyResult(goalId, krId) { const goal = wgt_goals.find(g => g.id === goalId); const kr = goal ? goal.keyResults.find(k => k.id === krId) : null; if (!kr) return; document.getElementById('wgt-keyResultId').value = kr.id; document.getElementById('wgt-krDescription').value = kr.description; document.getElementById('wgt-krDueDate').value = kr.dueDate || ''; document.getElementById('wgt-krIsDone').checked = kr.isDone; document.getElementById('wgt-cancelKrEditBtn').style.display = 'inline-block'; } function wgt_deleteKeyResult(goalId, krId) { const goalIndex = wgt_goals.findIndex(g => g.id === goalId); if (goalIndex === -1) return; if (confirm('Delete this key result?')) { wgt_goals[goalIndex].keyResults = wgt_goals[goalIndex].keyResults.filter(kr => kr.id !== krId); wgt_saveData(); wgt_renderKeyResultsList(goalId); wgt_renderGoalDashboard(); // Update progress } } function wgt_toggleKeyResultStatus(goalId, krId, isDone) { const goalIndex = wgt_goals.findIndex(g => g.id === goalId); if (goalIndex === -1) return; const krIndex = wgt_goals[goalIndex].keyResults.findIndex(kr => kr.id === krId); if (krIndex > -1) { wgt_goals[goalIndex].keyResults[krIndex].isDone = isDone; wgt_saveData(); wgt_renderKeyResultsList(goalId); // Re-render list for visual update (strikethrough) wgt_renderGoalDashboard(); // Update progress bar on dashboard } } function wgt_saveGoalReflection() { if (!wgt_currentGoalIdForManagement) return; const goalIndex = wgt_goals.findIndex(g => g.id === wgt_currentGoalIdForManagement); if (goalIndex > -1) { wgt_goals[goalIndex].reflectionNotes = document.getElementById('wgt-goalReflectionNotes').value.trim(); wgt_saveData(); alert("Reflection notes saved."); } } // --- Archived Goals Tab --- function wgt_renderArchivedGoals() { const listEl = document.getElementById('wgt-archivedGoalsList'); listEl.innerHTML = ''; const archivedGoals = wgt_goals.filter(goal => goal.status === 'Achieved' || goal.status === 'Cancelled'); if (archivedGoals.length === 0) { listEl.innerHTML = '
  • No goals have been archived yet.
  • '; return; } archivedGoals.sort((a,b)=> new Date(b.targetDate || 0) - new Date(a.targetDate || 0)); // Sort by most recent target date archivedGoals.forEach(goal => { const li = document.createElement('li'); li.style.borderLeftColor = goal.color || '#ccc'; li.innerHTML = `
    ${goal.name} - Status: ${goal.status}
    Target: ${goal.targetDate ? new Date(goal.targetDate+"T00:00:00").toLocaleDateString() : 'N/A'} | Progress: ${wgt_calculateGoalProgress(goal)}%
    `; listEl.appendChild(li); }); } function wgt_viewArchivedGoalDetails(goalId) { wgt_loadGoalForManagement(goalId, true); // Load in manage tab and switch // Potentially disable editing fields if it's just "viewing" archived } function wgt_unarchiveGoal(goalId) { const goalIndex = wgt_goals.findIndex(g => g.id === goalId); if (goalIndex > -1) { if (confirm(`Restore "${wgt_goals[goalIndex].name}" to active goals? It will be set to 'On Hold'.`)) { wgt_goals[goalIndex].status = 'On Hold'; // Or 'In Progress' wgt_saveData(); wgt_renderArchivedGoals(); wgt_renderGoalDashboard(); wgt_populateGoalSelectForManagement(); } } } // --- PDF Download --- document.getElementById('wgt-downloadPdfBtn').onclick = async () => { const { jsPDF } = window.jspdf; const pdf = new jsPDF('p', 'mm', 'a4'); let currentY = 15; const margin = 15; const contentWidth = pdf.internal.pageSize.getWidth() - 2*margin; const accentColor = '#10B981'; const textColor = '#047857'; pdf.setFontSize(18); pdf.setTextColor(accentColor); pdf.text("Work Goals Report", pdf.internal.pageSize.getWidth() / 2, currentY, { align: 'center' }); currentY += 8; pdf.setFontSize(10); pdf.setTextColor(textColor); pdf.text(`Report Generated: ${new Date().toLocaleDateString()}`, pdf.internal.pageSize.getWidth() / 2, currentY, { align: 'center'}); currentY += 10; const activeGoalsForPdf = wgt_goals.filter(g => g.status !== 'Achieved' && g.status !== 'Cancelled'); if (activeGoalsForPdf.length === 0) { pdf.text("No active goals to report.", margin, currentY); } activeGoalsForPdf.forEach(async (goal, index) => { if (index > 0 && currentY > pdf.internal.pageSize.getHeight() - 60) { // Check space for new goal section pdf.addPage(); currentY = margin; } const progress = wgt_calculateGoalProgress(goal); const goalColorRgb = wgt_hexToRgb(goal.color || accentColor); pdf.setFontSize(14); pdf.setTextColor(goal.color || accentColor); pdf.text(goal.name, margin, currentY); currentY += 6; pdf.setFontSize(9); pdf.setTextColor(textColor); pdf.text(`Status: ${goal.status} | Priority: ${goal.priority || 'N/A'} | Target: ${goal.targetDate ? new Date(goal.targetDate+"T00:00:00").toLocaleDateString() : 'N/A'}`, margin, currentY); currentY += 5; pdf.text(`Progress: ${progress}%`, margin, currentY); // Simple progress bar for PDF if (goalColorRgb) pdf.setFillColor(goalColorRgb.r, goalColorRgb.g, goalColorRgb.b); else pdf.setFillColor(16,185,129); pdf.rect(margin + 30, currentY - 3.5, 50 * (progress/100), 3, 'F'); // 50mm wide bar pdf.setDrawColor(100,100,100); pdf.rect(margin + 30, currentY - 3.5, 50, 3, 'S'); // Border currentY += 6; if (goal.description) { const descLines = pdf.splitTextToSize(`Description: ${goal.description}`, contentWidth); pdf.text(descLines, margin, currentY); currentY += (descLines.length * 4) + 2; } if (goal.keyResults && goal.keyResults.length > 0) { if (currentY > pdf.internal.pageSize.getHeight() - 20) { pdf.addPage(); currentY = margin; } pdf.setFontSize(10); pdf.setTextColor(textColor); pdf.text("Key Results:", margin, currentY); currentY += 5; const krBody = goal.keyResults.map(kr => [kr.description, kr.isDone ? "Done" : "To Do", kr.dueDate ? new Date(kr.dueDate+"T00:00:00").toLocaleDateString() : "-"]); pdf.autoTable({ head: [["Description", "Status", "Due Date"]], body: krBody, startY: currentY, theme: 'grid', headStyles: { fillColor: '#D1FAE5', textColor: '#047857' }, styles: { fontSize: 8, cellPadding:1.5 }, columnStyles: {0:{cellWidth: contentWidth * 0.5}, 1:{cellWidth:contentWidth*0.15}} }); currentY = pdf.lastAutoTable.finalY + 5; } if(goal.reflectionNotes){ if (currentY > pdf.internal.pageSize.getHeight() - 20) { pdf.addPage(); currentY = margin; } pdf.setFontSize(10); pdf.setTextColor(textColor); pdf.text("Reflection:", margin, currentY); currentY += 5; const reflectLines = pdf.splitTextToSize(goal.reflectionNotes, contentWidth); pdf.setFontSize(9); pdf.text(reflectLines, margin + 5, currentY); currentY += (reflectLines.length * 4) + 3; } currentY += 5; // Space between goals }); pdf.save(`Work_Goals_Report_${WGT_TODAY_CONTEXT.toISOString().slice(0,10)}.pdf`); }; function wgt_hexToRgb(hex) { const r = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); return r ? {r:parseInt(r[1],16),g:parseInt(r[2],16),b:parseInt(r[3],16)}:null;} // --- Initial Load --- document.addEventListener('DOMContentLoaded', () => { wgt_openTab(null, wgt_tabs[0]); // Redundant check if wgt_openTab correctly sets active class. // const firstTabButton = document.querySelector(`.wgt-tab-button[onclick*="'${wgt_tabs[0]}'"]`); // if (firstTabButton) firstTabButton.classList.add('active'); // else console.error("First tab button not found for initial activation."); wgt_updateNavButtons(); });
    Scroll to Top