Add trace files.
This commit is contained in:
111
docs/plans/sprint_1_story_3_task_3.md
Normal file
111
docs/plans/sprint_1_story_3_task_3.md
Normal file
@@ -0,0 +1,111 @@
|
||||
# Task 11: Integrate SignalR Real-time Updates
|
||||
|
||||
**Task ID**: TASK-011 | **Story**: [STORY-003](sprint_1_story_3.md) | **Sprint**: [Sprint 1](sprint_1.md)
|
||||
**Estimated Hours**: 3h | **Assignee**: Frontend Developer 1 | **Priority**: P1 | **Status**: Not Started
|
||||
|
||||
## Task Description
|
||||
Connect Kanban board to SignalR event handlers for real-time updates when Epic/Story/Task changes occur.
|
||||
|
||||
## Implementation
|
||||
|
||||
### Update KanbanBoard.tsx (2h)
|
||||
```typescript
|
||||
import { useEffect } from 'react';
|
||||
import { useSignalRContext } from '../services/signalr/SignalRContext';
|
||||
import { useQueryClient } from '@tanstack/react-query';
|
||||
|
||||
export const KanbanBoard: React.FC = () => {
|
||||
const { projectId } = useParams();
|
||||
const queryClient = useQueryClient();
|
||||
const { service, isConnected } = useSignalRContext();
|
||||
|
||||
// Subscribe to real-time events
|
||||
useEffect(() => {
|
||||
if (!isConnected || !service) return;
|
||||
|
||||
const handlers = service.getEventHandlers();
|
||||
if (!handlers) return;
|
||||
|
||||
// Epic events
|
||||
const unsubEpicCreated = handlers.subscribe('epic:created', (event) => {
|
||||
queryClient.invalidateQueries(['epics', projectId]);
|
||||
});
|
||||
|
||||
const unsubEpicUpdated = handlers.subscribe('epic:updated', (event) => {
|
||||
queryClient.setQueryData(['epics', projectId], (old: Epic[]) => {
|
||||
return old.map(e => e.id === event.epicId ? { ...e, ...event } : e);
|
||||
});
|
||||
});
|
||||
|
||||
const unsubEpicDeleted = handlers.subscribe('epic:deleted', (event) => {
|
||||
queryClient.setQueryData(['epics', projectId], (old: Epic[]) => {
|
||||
return old.filter(e => e.id !== event.epicId);
|
||||
});
|
||||
});
|
||||
|
||||
// Story events (similar)
|
||||
const unsubStoryCreated = handlers.subscribe('story:created', (event) => {
|
||||
queryClient.invalidateQueries(['stories', projectId]);
|
||||
});
|
||||
|
||||
// Task events (similar)
|
||||
const unsubTaskCreated = handlers.subscribe('task:created', (event) => {
|
||||
queryClient.invalidateQueries(['tasks', projectId]);
|
||||
});
|
||||
|
||||
const unsubTaskStatusChanged = handlers.subscribe('task:statusChanged', (event) => {
|
||||
// Animate card movement between columns
|
||||
queryClient.setQueryData(['tasks', projectId], (old: Task[]) => {
|
||||
return old.map(t => t.id === event.taskId ? { ...t, status: event.newStatus } : t);
|
||||
});
|
||||
});
|
||||
|
||||
// Cleanup subscriptions
|
||||
return () => {
|
||||
unsubEpicCreated();
|
||||
unsubEpicUpdated();
|
||||
unsubEpicDeleted();
|
||||
unsubStoryCreated();
|
||||
unsubTaskCreated();
|
||||
unsubTaskStatusChanged();
|
||||
};
|
||||
}, [isConnected, service, projectId, queryClient]);
|
||||
|
||||
// ... rest of component
|
||||
};
|
||||
```
|
||||
|
||||
### Add Card Animation (1h)
|
||||
```typescript
|
||||
// Use framer-motion for smooth animations
|
||||
import { motion } from 'framer-motion';
|
||||
|
||||
export const KanbanCard: React.FC<{ item: any }> = ({ item }) => {
|
||||
return (
|
||||
<motion.div
|
||||
layout
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
exit={{ opacity: 0, y: -20 }}
|
||||
transition={{ duration: 0.3 }}
|
||||
className="kanban-card"
|
||||
>
|
||||
{/* Card content */}
|
||||
</motion.div>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
## Acceptance Criteria
|
||||
- [ ] Kanban updates automatically on SignalR events
|
||||
- [ ] All 13 event types handled
|
||||
- [ ] Card animations smooth (60 FPS)
|
||||
- [ ] No duplicate cards after updates
|
||||
- [ ] Optimistic updates working
|
||||
|
||||
## Deliverables
|
||||
1. SignalR integration in KanbanBoard.tsx
|
||||
2. Card animations with framer-motion
|
||||
3. Integration tests (8+ scenarios)
|
||||
|
||||
**Status**: Not Started | **Created**: 2025-11-04
|
||||
Reference in New Issue
Block a user