Skip to content

Commit c36a4ae

Browse files
committed
Fix: Enable real-time updates for all work item fields in graph visualization
When users updated work item fields (priority, status, type) through modals, changes didn't reflect immediately in the interactive graph visualization. Only title updates worked correctly. Updated updateSimulationDataAndText function to refresh all visual elements: - Priority: progress bar, icon, percentage text - Status: progress bar, icon, percentage text, completion checkmark - Type: badge text, title bar color - Title text color (grayed when completed) All field updates now appear instantly without manual refresh.
1 parent 5999851 commit c36a4ae

1 file changed

Lines changed: 98 additions & 5 deletions

File tree

packages/web/src/components/InteractiveGraphVisualization.tsx

Lines changed: 98 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1449,12 +1449,18 @@ export function InteractiveGraphVisualization({ onResetLayout }: InteractiveGrap
14491449
.style('pointer-events', 'none');
14501450
});
14511451

1452-
// Update node type badge text
1452+
// Update node type badge text and title bar colors
1453+
const typeConfig = getTypeConfig(updatedNode.type as WorkItemType);
1454+
const isNodeCompleted = updatedNode.status === 'COMPLETED' || updatedNode.status === 'Completed' || updatedNode.status === 'Done' || updatedNode.status === 'DONE';
1455+
14531456
nodeGroup.select('.node-type-text')
1454-
.text(() => {
1455-
const config = getTypeConfig(updatedNode.type as WorkItemType);
1456-
return config.label.toUpperCase();
1457-
});
1457+
.text(typeConfig.label.toUpperCase())
1458+
.style('fill', typeConfig.hexColor);
1459+
1460+
// Update title bar colors based on type and status
1461+
nodeGroup.select('.node-title-bar')
1462+
.attr('fill', isNodeCompleted ? '#9ca3af' : typeConfig.hexColor)
1463+
.attr('stroke', isNodeCompleted ? '#6b7280' : typeConfig.hexColor);
14581464

14591465
// Update description
14601466
nodeGroup.select('.node-description-text')
@@ -1465,6 +1471,93 @@ export function InteractiveGraphVisualization({ onResetLayout }: InteractiveGrap
14651471
? updatedNode.description.substring(0, maxDescChars) + '...'
14661472
: updatedNode.description;
14671473
});
1474+
1475+
// Update priority indicators
1476+
const priority = updatedNode.priority || 0;
1477+
const priorityPercentage = Math.round(priority * 100);
1478+
const priorityColor = (() => {
1479+
if (priority >= 0.8) return '#dc2626';
1480+
if (priority >= 0.6) return '#f97316';
1481+
if (priority >= 0.4) return '#eab308';
1482+
if (priority >= 0.2) return '#3b82f6';
1483+
return '#6b7280';
1484+
})();
1485+
1486+
const barWidth = 40;
1487+
1488+
// Update priority progress bar fill
1489+
nodeGroup.select('.priority-progress-fill')
1490+
.attr('width', (barWidth * priorityPercentage) / 100)
1491+
.attr('fill', priorityColor);
1492+
1493+
// Update priority icon
1494+
const priorityIconPath = getPriorityIconSvgPath(priority);
1495+
const priorityIconSvg = nodeGroup.select('.priority-icon-svg');
1496+
priorityIconSvg.selectAll('path').remove();
1497+
if (priorityIconPath) {
1498+
priorityIconSvg.append('path')
1499+
.attr('d', priorityIconPath)
1500+
.attr('fill', 'none')
1501+
.attr('stroke', priorityColor)
1502+
.attr('stroke-width', '2')
1503+
.attr('stroke-linecap', 'round')
1504+
.attr('stroke-linejoin', 'round');
1505+
}
1506+
1507+
// Update priority percentage text
1508+
nodeGroup.select('.priority-percentage-text')
1509+
.text(`${priorityPercentage}%`)
1510+
.style('fill', priorityColor);
1511+
1512+
// Update status indicators
1513+
const statusPercentage = getStatusCompletionPercentage(updatedNode.status as WorkItemStatus);
1514+
const statusColor = getStatusConfig(updatedNode.status as WorkItemStatus).hexColor;
1515+
1516+
// Update status progress bar fill
1517+
nodeGroup.select('.status-progress-fill')
1518+
.attr('width', (barWidth * statusPercentage) / 100)
1519+
.attr('fill', statusColor);
1520+
1521+
// Update status icon
1522+
const statusIconPath = getStatusIconSvgPath(updatedNode.status as string);
1523+
const statusIconSvg = nodeGroup.select('.status-icon-svg');
1524+
statusIconSvg.selectAll('path').remove();
1525+
if (statusIconPath) {
1526+
statusIconSvg.append('path')
1527+
.attr('d', statusIconPath)
1528+
.attr('fill', 'none')
1529+
.attr('stroke', statusColor)
1530+
.attr('stroke-width', '2')
1531+
.attr('stroke-linecap', 'round')
1532+
.attr('stroke-linejoin', 'round');
1533+
}
1534+
1535+
// Update status percentage text
1536+
nodeGroup.select('.status-percentage-text')
1537+
.text(`${statusPercentage}%`)
1538+
.style('fill', statusColor);
1539+
1540+
// Update completion checkmark based on status
1541+
const isCompleted = updatedNode.status === 'COMPLETED' || updatedNode.status === 'Completed' || updatedNode.status === 'Done' || updatedNode.status === 'DONE';
1542+
const existingCheckmark = nodeGroup.select('.completion-indicator');
1543+
1544+
if (isCompleted && existingCheckmark.empty()) {
1545+
// Add checkmark if status is completed and it doesn't exist
1546+
nodeGroup.append('text')
1547+
.attr('class', 'completion-indicator')
1548+
.attr('text-anchor', 'middle')
1549+
.attr('dominant-baseline', 'central')
1550+
.attr('font-size', '96')
1551+
.attr('font-weight', '900')
1552+
.attr('fill', '#10b981')
1553+
.attr('stroke', '#10b981')
1554+
.attr('stroke-width', '1')
1555+
.attr('pointer-events', 'none')
1556+
.text('✓');
1557+
} else if (!isCompleted && !existingCheckmark.empty()) {
1558+
// Remove checkmark if status is not completed
1559+
existingCheckmark.remove();
1560+
}
14681561
});
14691562

14701563
// Gentle restart to settle any property changes

0 commit comments

Comments
 (0)