-
Notifications
You must be signed in to change notification settings - Fork 28
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
[Mission4/이혜준] - Project_Notion_VanillaJS #24
base: 3/#4_leehyejun
Are you sure you want to change the base?
[Mission4/이혜준] - Project_Notion_VanillaJS #24
Conversation
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.
혜준님 같이 팀해서 너무 좋았어요!
마지막 리뷰하러 방문했어용. 프로젝트 하느라 고생 많이하셨습니다.
@@ -0,0 +1,12 @@ | |||
<!DOCTYPE html> | |||
<html lang="en"> |
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.
ko면 더 좋을 거 같아요
if (className === "no-sub-page") { | ||
return; | ||
} |
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.
좋네요
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.
혜준님 노션 프로젝트 하시느라 고생하셨습니다!
꼼꼼한 성격답게 더미데이터로 체크하면서 코딩하신것 같아서 많이 배워가는 것 같습니다.
페이지 생성이나 삭제할때 토글리스트 닫히는건 혜준님이면 금방 하실것 같아요~~
한달동안 수고하셨고 다른 팀 가셔도 화이팅 하세용~
if (!isInitialize) { | ||
$editor.innerHTML = ` | ||
<input type="text" name="title" style="width: 600px;" value="${this.state.title}" /> | ||
<textarea name="content" style="width: 600px; height: 400px;">${this.state.content}</textarea> |
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.
style.scss파일이 있는데 여기서 따로 지정해둔 이유가 있을까요??
그리고 혹시 textarea 사이즈 고정을 원하시면 resize:none 을 주셔도 좋을 것 같습니당
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.
해당 스타일링 코드는 다른 커밋에서 scss파일로 옮겨두었습니다!
사용자가 마음대로 늘리게 하고 싶어서 resizeL none은 주지 않았어요 :)
if ($li) { | ||
const { id } = $li.dataset; | ||
const { className } = e.target; | ||
if (className === "post-delete") { | ||
onDelete(id); |
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.
문서삭제 같은 경우는 사용자에게 한번 더 물어보는게 어떨까요??
(배포하신거 사용해보다가 바로 삭제돼서 당황쓰..)
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.
생각해보니 지금 사용자가 실수로 사용했을 경우를 방지하지 않고 있어서 충분히 당황할 수 있을 것 같네요.
모달 창으로 삭제 여부를 물어보거나 노션처럼 삭제 후 되돌리기 기능을 넣는 것도 좋을 것 같아요! 의견 감사합니다 👍
@@ -40,6 +40,11 @@ export default function PostEditPage({ $target, initialState }) { | |||
} | |||
|
|||
removeItem(postLocalSaveKey); | |||
|
|||
this.setState({ | |||
postId: post.id + "", |
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.
저는 이거 일일히 toString()으로 사용했는데 이렇게 하면 훨씬 간결해지네요 👍
await request(`/documents/${postId}`, { | ||
method: "DELETE", | ||
}); | ||
}; |
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.
이렇게 한 곳에 모아두니까 너무 보기 좋네요 배워갑니다!
font-size: 20px; | ||
cursor: pointer; | ||
|
||
&:hover { |
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.
아 &를 이럴때 쓰는거네요..
저는 hover 효과 줄 때
.toggle-button:hover 이런식으로 하나를 또 만들었는데ㅋㅋㅋ 배워갑니당
} | ||
} | ||
|
||
.no-sub-page { | ||
padding-left: 39px; | ||
user-select: none; |
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.
이 user-select:none은 무슨 역할을 하나요??
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.
텍스트 드래그를 막는 역할을 합니다!
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.
안녕하세요 혜준님 코드리뷰 하러 왔습니다!
과제하시느라 수고 많으셨습니다 ~~
페이지 배포까지 하시다니 대단하세요!!
기능도 잘 작동하고 css 공들이신게 느껴질 정도로 노션과 똑같이 구현하셨네요 ~~ 👍
다음 과제도 화이팅 입니다!
/* 컬러 코드*/ | ||
$BROWN_10: #fbfbfa; | ||
$BROWN_20: #ebebea; | ||
$BROWN_30: #dddddc; | ||
$BROWN_40: #d3d1cb; | ||
$BROWN_50: #b5b5b2; | ||
$BROWN_60: #908f8c; | ||
$BROWN_70: #676662; | ||
$BROWN_80: #5e5c57; | ||
$BROWN_90: #37352f; |
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.
오 컬러코드 미리 지정해서 사용하는 거 좋네요
export const renderPosts = (root, posts, sub, down = false) => { | ||
let $ul = document.createElement("ul"); | ||
if (down) { | ||
$ul.classList.add("post-hide", "sub-post"); | ||
} | ||
root.appendChild($ul); | ||
|
||
posts.forEach((post) => { | ||
let $li = document.createElement("li"); | ||
$li.setAttribute("data-id", post.id); | ||
$li.innerHTML = ` | ||
<div class="post"> | ||
<div> | ||
<span> | ||
<button class="toggle-button" data-is-opened="false">▸</button> | ||
</span> | ||
<span class="post-title">${ | ||
post.title ? post.title : "제목 없음" | ||
}</span> | ||
</div> | ||
${ | ||
!sub | ||
? ` | ||
<div class="button-group"> | ||
<button class="post-create">✚</button> | ||
<button class="post-delete">✖</button> | ||
</div>` | ||
: "" | ||
} | ||
</div> | ||
`; | ||
|
||
$ul.appendChild($li); | ||
if (post.documents.length) { | ||
renderPosts($li, post.documents, sub, true); | ||
} else { | ||
let $ul = document.createElement("ul"); | ||
$ul.setAttribute("class", "post-hide"); | ||
$ul.innerHTML = `<span class="no-sub-page">하위 페이지 없음</span>`; | ||
$li.appendChild($ul); | ||
} | ||
}); | ||
}; |
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.
코드 보니까 서브 페이지 링크 구현 방식에 대해 이해가 되네요 👍 저도 나중에 구현해보겠습니다
export const toggle = ($button, $li) => { | ||
const { dataset, classList } = $button; | ||
const isOpened = JSON.parse(dataset.isOpened); | ||
const $ul = $li.querySelector("ul"); | ||
if ($ul) { | ||
!isOpened ? $ul.classList.remove("post-hide") : $ul.classList.add("post-hide"); | ||
} | ||
dataset.isOpened = !isOpened; | ||
if (!isOpened) { | ||
classList.add("open-toggle"); | ||
} else { | ||
classList.add("close-toggle"); | ||
setTimeout(() => { | ||
classList.remove("open-toggle", "close-toggle"); | ||
}, 300); | ||
} | ||
}; |
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.
토글 방식을 class를 이용해서 하는 방법이 있군요 배워갑니다 !!
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.
안녕하세요 혜준님~ 프로젝트 하느라 수고 많으셨습니다~
배포까지 하셔서 직접 사용해볼수있어서 너무 좋았습니다 ^^ 스타일링도 아주 깔끔하게 하셨구요..!!
editing하는 부분에 의견 살짝 남겨봤습니다~
let $ul = document.createElement("ul"); | ||
$ul.setAttribute("class", "post-hide"); | ||
$ul.innerHTML = `<span class="no-sub-page">하위 페이지 없음</span>`; | ||
$li.appendChild($ul); |
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.
이거 좋네요!
window.dispatchEvent(new CustomEvent("update-tree")); | ||
} |
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.
저도 이 부분 어떻게 처리할지 고민 많이 했는데 커스텀 이벤트를 활용하는것이 좋네요..!! 이것도 나중에 변수로 만들어내면 더 깔끔할것같다는 생각입니다~
this.setState({ | ||
postId: post.id + "", | ||
post, | ||
}); |
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.
editing 할때마다 this.setState => editor.setState하게되어 저장하면 form focus가 없어집니다. 제 생각에는 editing할때는 setState 없이 api 업데이트만 하고 page reload, push state할때만 setState 하면 더 좋을것같습니다~
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.
오 안그래도 이 부분 고민했었는데 감사합니다! 더 고민해보겠습니다
process.env는 Node 환경에 존재하는 환경변수입니다. (
근본적으론 포스트들의 오브젝트 모델을 가지고 DOM과 싱크하는 형태로 구조를 바꾸고, 필요한 부분만 렌더링되게 하는 방식으로 구현되어야 전체가 다 렌더링되는 문제가 근본적으로 해결될 수 있을 것 같아요. 혹은, rerender를 할 때 열고 닫혀있는 페이지들의 리스트를 user state를 저장하는 오브젝트 따위를 따로 두고 렌더링되는 시점에 이 state가 반영되게 하는 식으로도 문제 우회는 가능할 것 같아요.
앱이 시작하는 시점에서 초기화하는 것은 괜찮은 것 같습니다!
공통화를 잘 하신 것 같습니다! :)
|
}, | ||
}); | ||
|
||
this.route = () => { |
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.
route 보단 좀 더 구체적으로 어떤 동작을 하는지 설명하는 onRouteChange 같은 이름이 좋을 것 같아요!
|
||
this.render = () => { | ||
$postList.innerHTML = ""; | ||
this.state.length && renderPosts($postList, this.state, false); |
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.
이런 경우엔 short-circuit보단 (&&) if문을 이용하는 것이 더 보기 좋습니다.
await request(`/documents/${post.id}`, { | ||
method: "PUT", | ||
body: JSON.stringify(post), | ||
}); |
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.
사용부에서 await을 어짜피 하기 때문에 await을 하기보단 그냥 return을 하는게 낫지 않을까 생각됩니다!
let isInitialize = false; | ||
|
||
this.render = () => { | ||
if (!isInitialize) { |
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.
isInitialize 라는 별도의 변수를 두기보단, innerHTML이 비어있는지 여부로 체크도 가능할 것 같아요.
(가능하면 변수의 사용을 줄이는 것이 읽기 좋기에..)
📌 과제 설명
바닐라 JS만을 이용해 노션을 클로닝합니다.
현재 미완성된 기능이 많아서 코드리뷰 기간에도 계속해서 개발하고 스타일링하려고 합니다.
배포 링크
https://juns-notion.netlify.app/
페이지 생성, 수정, 삭제시 열려있던 하위 페이지들이 모두 닫히는 현상이 있습니다.. 😂
👩💻 요구 사항과 구현 내용
기본 요구사항
기본적인 레이아웃은 노션과 같으며, 스타일링, 컬러값 등은 원하는대로 커스텀합니다.
글 단위를 Document라고 합니다. Document는 Document 여러개를 포함할 수 있습니다.
보너스 요구사항
✅ PR 포인트 & 궁금한 점