-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[#54] Drag & Drop UI 구현 #55
Changes from 1 commit
a567ce6
f5512e6
45ebcb5
37f7b6d
23518da
39ab817
2edc94f
d28de4b
3579ebd
b53fb51
6ba5b8a
73a1bbe
c7c8f25
d8977d1
c3c721a
1d9ce0f
f5ab1aa
687efbe
b82e3b6
adb7645
bc44506
4c4b008
c51d1be
8d193a2
fccbd0d
171a5da
bb50263
39e17b5
db582ac
46fcc53
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -73,8 +73,6 @@ export const Column = ({ | |
}); | ||
|
||
// 카드리스트 가져오기 | ||
const [cardList, setCardList] = useState<CardData[]>([]); | ||
|
||
const getComments = async () => { | ||
const { id, size, cursorId } = pagination; | ||
let response; | ||
|
@@ -91,7 +89,6 @@ export const Column = ({ | |
setPagination((prevValue) => { | ||
return { ...prevValue, cursorId: cursor }; | ||
}); | ||
setCardList((prevValue) => [...prevValue, ...cards]); | ||
setEntireList((prev) => ({ | ||
...prev, | ||
cards: { ...prev.cards, [columnId]: [...(prev.cards[columnId] ?? []), ...cards] }, | ||
|
@@ -168,41 +165,38 @@ export const Column = ({ | |
|
||
return ( | ||
<> | ||
<div className={style.totalContainer}> | ||
{/* 칼럼 상단 */} | ||
<div className={style.headerContainer}> | ||
<div className={style.todoWrapper}> | ||
<ChipTodo size="sm" color="white"> | ||
{title} | ||
</ChipTodo> | ||
<ChipNum>{totalCount}</ChipNum> | ||
</div> | ||
<button onClick={handleSettingModalToggle}> | ||
<Image width={24} height={24} src="/icons/icon-settings.svg" alt="칼럼 설정하기" /> | ||
</button> | ||
</div> | ||
|
||
<div className={style.contentContainer}> | ||
{/* 컴포넌트로 바꾸기 */} | ||
<Button buttonType="plus_icon" color="white" onClick={handleCreateModalToggle}> | ||
<ChipPlus size="lg" /> | ||
</Button> | ||
<Droppable droppableId={String(columnId)}> | ||
{(provided) => ( | ||
<div {...provided.droppableProps} ref={provided.innerRef}> | ||
{entireList.cards[columnId]?.map((card, index) => ( | ||
<Card key={card.id} columnTitle={title} data={card} index={index} setCardList={setCardList} /> | ||
))} | ||
{provided.placeholder} | ||
<Droppable droppableId={String(columnId)}> | ||
{(provided) => ( | ||
<div {...provided.droppableProps} ref={provided.innerRef} className={style.totalContainer}> | ||
{/* 칼럼 상단 */} | ||
<div className={style.headerContainer}> | ||
<div className={style.todoWrapper}> | ||
<ChipTodo size="sm" color="white"> | ||
{title} | ||
</ChipTodo> | ||
<ChipNum>{totalCount}</ChipNum> | ||
</div> | ||
)} | ||
</Droppable> | ||
<p ref={myRef}></p> | ||
</div> | ||
</div> | ||
<button onClick={handleSettingModalToggle}> | ||
<Image width={24} height={24} src="/icons/icon-settings.svg" alt="칼럼 설정하기" /> | ||
</button> | ||
</div> | ||
|
||
<div className={style.contentContainer}> | ||
{/* 컴포넌트로 바꾸기 */} | ||
<Button buttonType="plus_icon" color="white" onClick={handleCreateModalToggle}> | ||
<ChipPlus size="lg" /> | ||
</Button> | ||
{entireList.cards[columnId]?.map((card, index) => ( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [ cards: {
columnA : [{컬럼 A 카드 A}, {컬럼 A 카드 B}],
columnB : [{컬럼 B 카드 A}, {컬럼 B 카드 B}],
columnC : [{컬럼 C 카드 A}, {컬럼 C 카드 B}],
}] 대충 이런 형태인가요? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @ayden94 |
||
<Card key={card.id} columnTitle={title} data={card} index={index} setEntireList={setEntireList} /> | ||
))} | ||
<p ref={myRef}></p> | ||
</div> | ||
{provided.placeholder} | ||
</div> | ||
)} | ||
</Droppable> | ||
{isSettingModalOpen && ( | ||
<ModalWrapper size="md"> | ||
<ModalWrapper size="md" handleModalClose={handleSettingModalToggle}> | ||
<form className={stylesFromSingle.form} onSubmit={handleModifyColumn} noValidate> | ||
<div className={stylesFromSingle.modal}> | ||
<div className={stylesFromSingle.modalTitle}>컬럼 관리</div> | ||
|
@@ -236,7 +230,6 @@ export const Column = ({ | |
)} | ||
{isCreateModalOpen && ( | ||
<MultiInputModal | ||
setCardList={setCardList} | ||
setEntireList={setEntireList} | ||
title="할 일 생성" | ||
buttonText="생성" | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
import useApi from "@/hooks/useApi"; | ||
import EditInputModal from "@/modals/EditInputModal"; | ||
import CommentList from "@/modals/components/Comment/CommentList"; | ||
import { CardData } from "@/types/api.type"; | ||
import { CardData, EntireData } from "@/types/api.type"; | ||
import { getAccessTokenFromDocument } from "@/utils/getAccessToken"; | ||
import Image from "next/image"; | ||
import { Dispatch, FocusEvent, FormEvent, SetStateAction, useRef, useState } from "react"; | ||
|
@@ -15,11 +15,11 @@ import AssigneeAndDueDateInfo from "./components/AssigneeAndDueDateInfo/Assignee | |
interface TaskCardInfoProps { | ||
columnTitle: string; | ||
data: CardData; | ||
setCardList: Dispatch<SetStateAction<CardData[]>>; | ||
setEntireList: Dispatch<SetStateAction<EntireData>>; | ||
handleModalClose: () => void; | ||
} | ||
|
||
const TaskCardModal = ({ data, columnTitle, setCardList, handleModalClose }: TaskCardInfoProps) => { | ||
const TaskCardModal = ({ data, columnTitle, setEntireList, handleModalClose }: TaskCardInfoProps) => { | ||
const [isKebabOpen, setIsKebabOpen] = useState(false); | ||
const [isCardModifyModalOpen, setCardModifyModalOpen] = useState(false); | ||
const [isCardDeleteModalOpen, setCardDeleteModalOpen] = useState(false); | ||
|
@@ -62,10 +62,15 @@ const TaskCardModal = ({ data, columnTitle, setCardList, handleModalClose }: Tas | |
if (res?.status === 204) { | ||
handleDeleteModalToggle(); | ||
handleModalClose(); | ||
setCardList((prevValue) => { | ||
const newCardList = prevValue.filter((card) => card.id !== data.id); | ||
return newCardList; | ||
}); | ||
setEntireList( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 모든 카드 부분을 이거로 바꾸다니.. 갱장한 노가다였겠군요 ㄷㄷ |
||
(prev) => ( | ||
delete prev.columns[data.columnId], | ||
{ | ||
...prev, | ||
columnOrder: prev.columnOrder.filter((id) => id !== data.columnId), | ||
} | ||
) | ||
); | ||
} | ||
}; | ||
|
||
|
@@ -94,7 +99,7 @@ const TaskCardModal = ({ data, columnTitle, setCardList, handleModalClose }: Tas | |
title="할 일 수정" | ||
columnTitle={columnTitle} | ||
buttonText="수정" | ||
setCardList={setCardList} | ||
setEntireList={setEntireList} | ||
handleModalClose={handleModifyModalToggle} | ||
/> | ||
)} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,7 +15,8 @@ import { getAccessTokenFromCookie } from "@/utils/getAccessToken"; | |
import { GetServerSidePropsContext, InferGetServerSidePropsType } from "next"; | ||
import { FormEvent, useCallback, useEffect, useState } from "react"; | ||
import style from "./dashboard.module.css"; | ||
import { DragDropContext } from "@hello-pangea/dnd"; | ||
import { DragDropContext, DropResult } from "@hello-pangea/dnd"; | ||
import { useRouter } from "next/router"; | ||
|
||
export const getServerSideProps = async (context: GetServerSidePropsContext) => { | ||
const accessToken = getAccessTokenFromCookie(context) as string; | ||
|
@@ -102,18 +103,37 @@ const Dashboard = ({ | |
} | ||
}; | ||
|
||
const [mounted, setMounted] = useState(false); | ||
const [mount, setMount] = useState(false); | ||
const router = useRouter(); | ||
|
||
useEffect(() => { | ||
setMounted(true); | ||
setMount(true); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이거는 혹시 다른 코드랑 중복되는, 가령 라이브러리의 예약어라던가, 그런 게 있었던 건가요?? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아뇨?? 아마 코드가 지워졌는데 제가 mounted 랑 mount 헷갈린거같아요 |
||
setEntireList(entireData); | ||
}, [entireData]); | ||
|
||
const onDragEnd = useCallback(() => {}, []); | ||
|
||
if (!mounted) return null; | ||
|
||
console.log(entireList); | ||
}, [router.query.boardId]); | ||
|
||
const onDragEnd = useCallback((result: DropResult) => { | ||
const { destination, source, draggableId } = result; | ||
if (!destination) return; | ||
if (destination.droppableId === source.droppableId) return; | ||
if (destination.droppableId === source.droppableId && source.index === destination.index) return; | ||
|
||
console.log(entireList); | ||
console.log(source.droppableId, destination.droppableId); | ||
const dragStartColumnId = Number(source.droppableId); | ||
const startCardList = entireList.cards[dragStartColumnId]; | ||
const movingCard = startCardList.splice(source.index, 1); | ||
|
||
const dragEndColumnId = Number(destination.droppableId); | ||
const endCardList = entireList.cards[dragEndColumnId]; | ||
endCardList.splice(destination.index, 0, ...movingCard); | ||
|
||
setEntireList((prev) => ({ | ||
...prev, | ||
cards: { ...prev.cards, [dragStartColumnId]: startCardList, [dragEndColumnId]: endCardList }, | ||
})); | ||
}, []); | ||
|
||
if (!mount) return; | ||
return ( | ||
<> | ||
{/* 대시보드에 맞는 레이아웃으로 설정-헤더 수정 */} | ||
|
@@ -150,7 +170,7 @@ const Dashboard = ({ | |
</MenuLayout> | ||
|
||
{isCreateModal && ( | ||
<ModalWrapper size="md"> | ||
<ModalWrapper size="md" handleModalClose={handleCreateNewColumnModalToggle}> | ||
<form className={stylesFromSingle.form} onSubmit={handleSubmit} noValidate> | ||
<div className={stylesFromSingle.modal}> | ||
<div className={stylesFromSingle.modalTitle}>새 컬럼 생성</div> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이건 결국 그럼 모든 컬럼에 있는 모든 카드를 하나의 스테이트에서 가져오기로 한 거군요