Skip to content

Commit 532f8f5

Browse files
authored
Merge pull request #67 from cortex-reply/fix/minor-fixes
fix: minor fixes
2 parents e18e664 + 43b5115 commit 532f8f5

3 files changed

Lines changed: 81 additions & 34 deletions

File tree

src/components/Projects/KanbanBoardView.tsx

Lines changed: 60 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ export interface KanbanBoardProps {
2121
initialColleagues?: Colleague[]
2222
// Task handlers
2323
onAddTask?: (newTask: Omit<Task, 'id' | 'createdAt' | 'updatedAt'>) => void
24-
onUpdateTask?: (taskId: string, updates: Partial<Task>) => Promise<Task>
24+
onUpdateTask?: (taskId: string, updates: Partial<Task>) => void
2525
onDeleteTask?: (taskId: string) => void
2626
onTaskClick?: (task: Task) => void
2727
// Epic handlers
2828
onAddEpic?: (newEpic: Omit<Epic, 'id' | 'updatedAt' | 'createdAt'>) => void
29-
onAddComment?: ({ content, taskId }: { taskId: string; content: string }) => Promise<Task>
29+
onAddComment?: ({ content, taskId }: { taskId: string; content: string }) => void
3030
}
3131

3232
export const KanbanBoardView: React.FC<KanbanBoardProps> = ({
@@ -45,39 +45,77 @@ export const KanbanBoardView: React.FC<KanbanBoardProps> = ({
4545
onAddEpic,
4646
onAddComment,
4747
}) => {
48-
const [tasks, setTasks] = useState<Task[]>(initialTasks)
49-
const [epics, setEpics] = useState<Epic[]>(initialEpics)
50-
const [sprints, setSprints] = useState<(Sprint & { isSelected: boolean })[]>(initialSprints)
48+
const [tasks, setTasks] = useState<Task[]>([])
49+
const [epics, setEpics] = useState<Epic[]>([])
50+
const [sprints, setSprints] = useState<(Sprint & { isSelected: boolean })[]>([])
5151
const [isAddTaskModalOpen, setIsAddTaskModalOpen] = useState(false)
5252
const [isAddEpicModalOpen, setIsAddEpicModalOpen] = useState(false)
5353
const [selectedTask, setSelectedTask] = useState<Task | null>(null)
5454
const [draggedTask, setDraggedTask] = useState<Task | null>(null)
55-
const [users, setUsers] = useState<User[]>(initialUsers)
56-
const [colleagues, setColleagues] = useState<Colleague[]>(initialColleagues)
55+
const [users, setUsers] = useState<User[]>([])
56+
const [colleagues, setColleagues] = useState<Colleague[]>([])
5757
const [heroHeight, setHeroHeight] = useState(0)
5858

5959
const heroRef = useRef<HTMLDivElement>(null)
6060
const containerRef = useRef<HTMLDivElement>(null)
61+
const selectedEpicIds = React.useMemo(
62+
() => [...epics.map((e) => e.id), 0], // include “no-epic” sentinel id 0
63+
[epics],
64+
)
6165

62-
const selectedEpics = epics.filter((epic) => true).map((epic) => epic.id)
63-
const selectedSprint = sprints.find((sprint) => sprint.isSelected)
66+
const prevTaskHash = useRef<string>('')
67+
const prevEpicHash = useRef<string>('')
68+
const prevSprintHash = useRef<string>('')
69+
const prevColleagueHash = useRef<string>('')
6470

65-
selectedEpics.push(0)
71+
const getHash = (list: { id: string | number; createdAt: string; updatedAt: string }[]) => {
72+
return list
73+
.map(
74+
(item) =>
75+
`${item.id}-${new Date(item.createdAt).getTime()}-${new Date(item.updatedAt).getTime()}`,
76+
)
77+
.join('-')
78+
}
6679

6780
useEffect(() => {
68-
setTasks(initialTasks)
81+
const next = getHash(initialTasks)
82+
if (next !== prevTaskHash.current) {
83+
setTasks(initialTasks)
84+
if (selectedTask) {
85+
setSelectedTask(initialTasks.find((task) => task.id === selectedTask.id) || null)
86+
}
87+
prevTaskHash.current = next
88+
}
6989
}, [initialTasks])
7090

7191
useEffect(() => {
72-
setEpics(initialEpics)
92+
const next = getHash(initialEpics)
93+
if (next !== prevEpicHash.current) {
94+
setEpics(initialEpics)
95+
prevEpicHash.current = next
96+
}
7397
}, [initialEpics])
7498

7599
useEffect(() => {
76-
setSprints(initialSprints)
100+
const next = getHash(initialSprints)
101+
if (next !== prevSprintHash.current) {
102+
setSprints(initialSprints)
103+
prevSprintHash.current = next
104+
}
77105
}, [initialSprints])
78106

79107
useEffect(() => {
80-
setColleagues(initialColleagues)
108+
const next = getHash(
109+
initialColleagues.map((el) => ({
110+
id: el.id,
111+
updatedAt: el.updatedAt,
112+
createdAt: el.createdAt,
113+
})),
114+
)
115+
if (next !== prevColleagueHash.current) {
116+
setColleagues(initialColleagues)
117+
prevColleagueHash.current = next
118+
}
81119
}, [initialColleagues])
82120

83121
// Measure hero height and adjust when it changes
@@ -90,6 +128,7 @@ export const KanbanBoardView: React.FC<KanbanBoardProps> = ({
90128
}
91129

92130
// Initial measurement
131+
93132
measureHeroHeight()
94133

95134
// Set up ResizeObserver to watch for changes in hero height
@@ -170,18 +209,17 @@ export const KanbanBoardView: React.FC<KanbanBoardProps> = ({
170209
onAddTask?.(newTask)
171210
}
172211

173-
const handleUpdateTask = async (taskId: string, updates: Partial<Task>): Promise<Task> => {
212+
const handleUpdateTask = async (taskId: string, updates: Partial<Task>): Promise<void> => {
174213
setTasks((prev) =>
175214
prev.map((task) => (task.id === Number(taskId) ? { ...task, ...updates } : task)),
176215
)
177216
if (onUpdateTask) {
178-
return await onUpdateTask(taskId, updates)
217+
await onUpdateTask(taskId, updates)
179218
}
180-
const task = tasks.find((task) => task.id === Number(taskId))
181-
if (!task) {
182-
throw new Error('Task not found')
219+
220+
if (selectedTask?.id === Number(taskId)) {
221+
setSelectedTask((prev) => ({ ...prev, ...updates } as Task))
183222
}
184-
return { ...task, ...updates }
185223
}
186224

187225
const handleDeleteTask = async (taskId: string): Promise<void> => {
@@ -265,6 +303,7 @@ export const KanbanBoardView: React.FC<KanbanBoardProps> = ({
265303
{tasksByEpic['no-epic'].map((task) => {
266304
return (
267305
<TaskCard
306+
key={task.id}
268307
epic={null}
269308
task={task}
270309
onDragStart={handleDragStart}
@@ -273,7 +312,7 @@ export const KanbanBoardView: React.FC<KanbanBoardProps> = ({
273312
/>
274313
)
275314
})}
276-
{selectedEpics.map((epicId) => {
315+
{selectedEpicIds.map((epicId) => {
277316
const epic = epics.find((e) => e.id === epicId)
278317
const epicTasks = tasksByEpic[epicId] || []
279318

src/components/Projects/TaskDetailsModal.tsx

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ interface TaskDetailsModalProps {
2121
initialTask: Task
2222
epics: Epic[]
2323
sprints: Sprint[]
24-
onUpdateTask: (taskId: string, updates: Partial<Task>) => Promise<Task>
24+
onUpdateTask: (taskId: string, updates: Partial<Task>) => void
2525
onDeleteTask: (taskId: string) => Promise<void>
26-
onAddComment?: ({ content, taskId }: { taskId: string; content: string }) => Promise<Task>
26+
onAddComment?: ({ content, taskId }: { taskId: string; content: string }) => void
2727
colleagues: Colleague[]
2828
}
2929

@@ -66,8 +66,8 @@ export const TaskDetailsModal: React.FC<TaskDetailsModalProps> = ({
6666
if (value !== task[fieldName as keyof Task]) {
6767
setUpdateState('loading')
6868
try {
69-
const updatedTask = await onUpdateTask(task.id.toString(), { [fieldName]: value })
70-
setTask(updatedTask)
69+
await onUpdateTask(task.id.toString(), { [fieldName]: value })
70+
// setTask(updatedTask)
7171
setLastUpdated(new Date())
7272
setUpdateState('success')
7373
// Reset to idle after showing success
@@ -85,8 +85,8 @@ export const TaskDetailsModal: React.FC<TaskDetailsModalProps> = ({
8585
if (value !== task[fieldName as keyof Task]) {
8686
setUpdateState('loading')
8787
try {
88-
const updatedTask = await onUpdateTask(task.id.toString(), { [fieldName]: value })
89-
setTask(updatedTask)
88+
await onUpdateTask(task.id.toString(), { [fieldName]: value })
89+
// setTask(updatedTask)
9090
setLastUpdated(new Date())
9191
setUpdateState('success')
9292
// Reset to idle after showing success
@@ -104,8 +104,8 @@ export const TaskDetailsModal: React.FC<TaskDetailsModalProps> = ({
104104
if (!onAddComment) return
105105
setUpdateState('loading')
106106
try {
107-
const updatedTask = await onAddComment?.({ content: text, taskId: task.id.toString() })
108-
setTask(updatedTask)
107+
await onAddComment?.({ content: text, taskId: task.id.toString() })
108+
// setTask(updatedTask)
109109
setLastUpdated(new Date())
110110
setUpdateState('success')
111111
// Reset to idle after showing success
@@ -185,7 +185,7 @@ export const TaskDetailsModal: React.FC<TaskDetailsModalProps> = ({
185185
<Dialog open={isOpen} onOpenChange={handleClose}>
186186
<DialogContent className="max-w-3xl max-h-[80vh] overflow-y-auto p-4">
187187
<DialogHeader>
188-
<DialogTitle className="sr-only">{task.name}</DialogTitle>
188+
<DialogTitle className="sr-only">{task?.name}</DialogTitle>
189189
<div className="flex items-center justify-between">
190190
<div className="flex-1">{renderStatusIndicator()}</div>
191191
{!canClose && <div className="text-xs text-muted-foreground">Please wait...</div>}

src/components/Projects/file-list.tsx

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,16 @@ import { MoreHorizontal, Trash2, Edit } from 'lucide-react'
55
import { Button } from '@/components/ui/button'
66
import { File as FileType } from '../Foundary/types'
77

8+
const formatFileSize = (bytes?: number | null): string => {
9+
if (!bytes || bytes <= 0) return '0 KB'
10+
const kilobytes = bytes / 1024
11+
if (kilobytes < 1024) {
12+
return `${kilobytes.toFixed(2)} KB`
13+
}
14+
const megabytes = kilobytes / 1024
15+
return `${megabytes.toFixed(2)} MB`
16+
}
17+
818
interface FileListProps {
919
files: FileType[]
1020
onFileClick?: (file: FileType) => void
@@ -47,12 +57,10 @@ export function FileList({
4757
<p className="font-medium">{file.name}</p>
4858
</div>
4959
</div>
50-
<div className="col-span-2 text-sm md:text-base">{file.filesize}</div>
60+
<div className="col-span-2 text-sm md:text-base">{formatFileSize(file.filesize)}</div>
5161
<div className="col-span-2 flex items-center justify-between w-full md:w-auto">
5262
<span className="text-sm md:text-base">
53-
{typeof file.createdAt === 'string'
54-
? file.createdAt
55-
: new Date(file.createdAt).toLocaleDateString()}
63+
{new Date(file.createdAt).toLocaleDateString()}
5664
</span>
5765
<div className="flex gap-1">
5866
{/* <Button

0 commit comments

Comments
 (0)