Project Scope Dashboard
No scope changes logged.
';
return;
}
container.innerHTML = recentChanges.map(c => `
${c.Description}
${c.Date}
`).join('');
}
function renderDeliverablesTable() {
const table = document.getElementById('deliverables-table');
table.innerHTML = `
| Deliverable Name | Owner | Status | Actions |
${deliverablesData.map(d => `
|
|
|
|
`).join('')}
`;
}
function renderChangesTable() {
const table = document.getElementById('changes-table');
table.innerHTML = `
| Date | Description | Impact | Actions |
${changesData.map(c => `
|
|
|
|
`).join('')}
`;
}
// --- CRUD Functions & Event Listeners (FIXED) ---
function addDeliverable() {
deliverablesData.push({ id: Date.now(), Name: 'New Deliverable', Owner: 'Unassigned', Status: 'Not Started' });
renderAll();
};
function addChange() {
changesData.unshift({ id: Date.now(), Date: new Date().toISOString().split('T')[0], Description: 'New scope change', Impact: 'Added to Scope' });
renderAll();
};
function handleTableEdit(e, dataArray) {
const id = parseInt(e.target.closest('tr').dataset.id);
const key = e.target.dataset.key;
const value = e.target.value;
const item = dataArray.find(d => d.id === id);
if (item) item[key] = value;
renderAll();
}
document.getElementById('psd-add-deliverable-btn').addEventListener('click', addDeliverable);
document.getElementById('psd-add-change-btn').addEventListener('click', addChange);
const deliverablesTable = document.getElementById('deliverables-table');
deliverablesTable.addEventListener('change', (e) => handleTableEdit(e, deliverablesData));
deliverablesTable.addEventListener('click', (e) => {
if(e.target.classList.contains('remove-deliverable-btn')) {
const id = parseInt(e.target.dataset.id);
deliverablesData = deliverablesData.filter(d => d.id !== id);
renderAll();
}
});
const changesTable = document.getElementById('changes-table');
changesTable.addEventListener('change', (e) => handleTableEdit(e, changesData));
changesTable.addEventListener('click', (e) => {
if(e.target.classList.contains('remove-change-btn')) {
const id = parseInt(e.target.dataset.id);
changesData = changesData.filter(c => c.id !== id);
renderAll();
}
});
function initialize() {
deliverablesData = [
{ id: 1, Name: 'User Authentication Module', Owner: 'Team A', Status: 'Completed' },
{ id: 2, Name: 'Admin Dashboard Interface', Owner: 'Team B', Status: 'In Progress' },
{ id: 3, Name: 'Reporting Engine', Owner: 'Team A', Status: 'In Progress' },
{ id: 4, Name: 'Payment Gateway Integration', Owner: 'Team C', Status: 'Not Started' },
{ id: 5, Name: 'User Profile Pages', Owner: 'Team B', Status: 'Completed' },
{ id: 6, Name: 'Mobile App Support (Phase 2)', Owner: 'Team D', Status: 'Out of Scope' },
];
initialDeliverableCount = deliverablesData.filter(d => d.Status !== 'Out of Scope').length;
changesData = [
{ id: 1, Date: '2025-06-15', Description: 'Add social media login options', Impact: 'Added to Scope' },
{ id: 2, Date: '2025-06-20', Description: 'Remove legacy reporting feature', Impact: 'Removed from Scope' },
];
renderAll();
}
initialize();
});