칸반 목록 저장 이슈 해결#73
Conversation
- task.ts: 할 일 단건 수정 API(PATCH) 함수 추가 - useKanbanDnd.ts: 드래그로 컬럼 이동 시 onStatusChange 콜백 호출 - useKanbanTasks.ts: handleStatusChange 훅 추가 — localStorage로 컬럼 위치 유지, done/todo 이동 시 전체 항목, inProgress 이동 시 단일 항목 완료 상태 API 요청 - KanbanBoard.tsx: handleStatusChange를 useKanbanDnd에 전달
- 빈 컬럼 드롭 영역 min-height 40px → 200px로 확장 - 드래그 중인 아이템 원본 위치에 테두리 플레이스홀더 표시 (border-radius 12px) - 대상 컬럼 진입 시 드롭 위치 가이드 사각형 표시 (드래그 아이템과 동일 크기) - inProgress 컬럼 이동 시 불필요한 API 호출 제거로 자유로운 양방향 이동 지원
Summary of ChangesHello @Jieunsse, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! 이 PR은 칸반 보드의 사용자 경험을 개선하기 위해 두 가지 주요 기능을 도입합니다. 첫째, 사용자가 드래그 앤 드롭으로 할 일 목록의 상태를 변경할 때, 이 상태가 로컬 스토리지에 저장되어 페이지를 새로고침해도 유지됩니다. 둘째, 드래그 중인 카드가 놓일 위치를 명확하게 보여주는 시각적 드롭 가이드를 추가하여 드래그 앤 드롭의 직관성을 높였습니다. 또한, 할 일 목록의 상태 변경이 백엔드 API를 통해 태스크의 완료 상태와 동기화되도록 하여 데이터 일관성을 확보했습니다. Highlights
🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Changelog
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
칸반 보드의 상태 저장 및 드래그 미리보기 기능 추가를 위한 변경 사항들을 잘 확인했습니다. 전반적으로 기능 구현이 잘 이루어졌습니다. 코드의 효율성과 유지보수성을 높이기 위해 몇 가지 개선점을 제안합니다. useKanbanDnd 훅에서 중복되는 로직을 통합하고, useKanbanTasks 훅에서 useCallback 의존성을 최적화하며, KanbanColumn 컴포넌트에서 하드코딩된 값을 상수로 관리하는 것을 고려해 보세요. 자세한 내용은 각 파일에 남긴 주석을 참고해 주세요.
| const showDropGuide = !!active && !isActiveFromThisColumn && (isOver || isOverThisColumnItem); | ||
|
|
||
| // 드래그 중인 아이템의 초기 높이 (가이드 크기를 아이템과 동일하게 맞추기 위함) | ||
| const draggedItemHeight = active?.rect.current.initial?.height ?? 54; |
| setTasks((prev) => | ||
| prev.map((t) => (t.id === activeId ? { ...t, status: overId as KanbanStatus } : t)), | ||
| ); | ||
| const activeTaskItem = tasks.find((t) => t.id === activeId); |
| const handleStatusChange = useCallback( | ||
| async (taskId: string, fromStatus: KanbanStatus, toStatus: KanbanStatus) => { | ||
| if (fromStatus === toStatus) return; | ||
|
|
||
| const task = tasks.find((t) => t.id === taskId); | ||
| const taskListId = Number(taskId); | ||
|
|
||
| // 항목 유무와 관계없이 컬럼 위치를 localStorage에 저장 | ||
| setStoredStatus(groupId, taskListId, toStatus); | ||
|
|
||
| // 진행중으로 이동하거나 항목이 없으면 API 호출 없이 종료 (위치는 이미 저장됨) | ||
| if (!task || task.items.length === 0 || toStatus === 'inProgress') return; | ||
|
|
||
| try { | ||
| if (toStatus === 'done') { | ||
| // 모든 항목 완료 처리 | ||
| await Promise.all( | ||
| task.items.map((item) => | ||
| updateTask(groupId, taskListId, Number(item.id), { done: true }), | ||
| ), | ||
| ); | ||
| } else if (toStatus === 'todo') { | ||
| // 모든 항목 미완료 처리 | ||
| await Promise.all( | ||
| task.items.map((item) => | ||
| updateTask(groupId, taskListId, Number(item.id), { done: false }), | ||
| ), | ||
| ); | ||
| } | ||
| } finally { | ||
| // 성공/실패 관계없이 쿼리를 무효화하여 실제 서버 상태로 동기화 | ||
| await queryClient.invalidateQueries({ | ||
| queryKey: taskListKeys.detail(groupId, taskListId, today), | ||
| }); | ||
| } | ||
| }, | ||
| [tasks, groupId, today, queryClient], | ||
| ); |
Summary
Issue