From c1f2afb528ebda7ffe936ed83d7e9e50f0b2ef5c Mon Sep 17 00:00:00 2001 From: Seung-hwan285 Date: Thu, 17 Nov 2022 00:28:58 +0900 Subject: [PATCH 01/29] initial commit project --- .gitignore | 27 +++++++++++++++++++++++++++ README.md | 23 ++++++++++++++++++++++- index.html | 13 +++++++++++++ main.js | 6 ++++++ package.json | 33 +++++++++++++++++++++++++++++++++ src/App.js | 15 +++++++++++++++ src/style/index.css | 0 src/utils/util.js | 2 ++ 8 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100644 index.html create mode 100644 main.js create mode 100644 package.json create mode 100644 src/App.js create mode 100644 src/style/index.css create mode 100644 src/utils/util.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..6bc83e14 --- /dev/null +++ b/.gitignore @@ -0,0 +1,27 @@ +# dependencies +/node_modules +/package-lock.json +/.pnp +.pnp.js + +# intellij configs +.idea/ + +# testing +/coverage + +# production +/build + +# misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* + + diff --git a/README.md b/README.md index 82b85e81..e6b163f8 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,31 @@ ## 필수 프로젝트 +글 단위를 Document라고 합니다. Document는 Document 여러개를 포함할 수 있습니다. +- [x] 화면 좌측에 Root Documents를 불러오는 API를 통해 root Documents를 렌더링합니다. +- [x] Root Documents를 클릭하면 오른쪽 편집기 영역에 해당 Docuement의 Content를 렌더링 합니다. +- [x] 해당 Root Document에 하위 Document가 있는 경우 , 해당 Document 아래에 트리 형태로 렌더링 합니다. +- [x] Document Tree에서 각 Document 우측에는 + 버튼이 있습니다. 해당 버튼을 클릭하면 , 클릭한 Document의 하위 Document로 새 Document를 생성하고 편집화면으로 넘깁니다. +- [x] 편집기에는 기본적으로 저장 버튼이 없습니다. Document Save API를 이용해 지속적으로 서버에 저장되도록 합니다. +- [x] History API를 이용해 SPA형태로 만듭니다. +- [x] 루트 URL 접속 시엔 별다른 편집기 선택이 안된 상태입니다. +- [x] /documents/{documentId} 로 접속시 , 해당 Document의 content를 불러와 편집기에 로딩합니다. +- [x] Header 버튼 클릭하면 정상적으로 새로운 Document가 생성되는데 초기값 null 들어가는 현상 +- [x] '제목없음' ,'내용없음' 초기에 grey color , input 들어오면 색 변경 +- [x] putMethod 404 Error +- [x] Editor content 부분 textarea 값 변경 안되는 현상 +- [x] Editor content 부분 입력할때 textarea 2 개행 이상부터 안보이는 현상 +- [x] 상위 Document 삭제하면 하위 Document도 같이 삭제가 되야 하는데 상위 Document 밑으로 이동 되는 현상 +- [ ] Editor content 부분 textarea 렌더링 했을때 2 개행 이상부터 잘려서 안나오는 현상 +- [ ] 버튼 이미지 넣어서 관리 -> 현재 text로 들어가 있음 +- [ ] 편집기 하단에는 Documents의 하위 Document 링크를 렌더링하도록 생성 +- [ ] 예외처리 작업 + + - 프로젝트 기한 - 프로젝트 수행 기간 : 2022년 11월 8일(화) ~ 2022년 11월 16일(수) - 멘티 코드 리뷰 기간 : 2022년 11월 17일(목) ~ 2022년 11월 20일(일) - 멘토 코드 리뷰 기간 : 2022년 11월 17일(목) ~ 2022년 11월 22일(화) - 코드 리뷰 반영 기간 : 2022년 11월 23일(수) ~ 2022년 11월 25일(금) - 내용 - - **Day 17 [프로젝트] 노션 클로닝 요구사항** 확인 부탁드립니다. + - **Day 17 [프로젝트] 노션 클로닝 요구사항** 확인 부탁드립니다. \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 00000000..8694c145 --- /dev/null +++ b/index.html @@ -0,0 +1,13 @@ + + + + + Title + + + +
+ + + + diff --git a/main.js b/main.js new file mode 100644 index 00000000..121d316f --- /dev/null +++ b/main.js @@ -0,0 +1,6 @@ +import App from "./src/App.js"; + +const app = document.querySelector('.app'); + + +new App({target :app}); \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 00000000..76ea3e81 --- /dev/null +++ b/package.json @@ -0,0 +1,33 @@ +{ + "name": "fedc3-4_project_notion_vanillajs", + "version": "1.0.0", + "description": "- 프로젝트 기한\r - 프로젝트 수행 기간 : 2022년 11월 8일(화) ~ 2022년 11월 16일(수)\r - 멘티 코드 리뷰 기간 : 2022년 11월 17일(목) ~ 2022년 11월 20일(일)\r - 멘토 코드 리뷰 기간 : 2022년 11월 17일(목) ~ 2022년 11월 22일(화)\r - 코드 리뷰 반영 기간 : 2022년 11월 23일(수) ~ 2022년 11월 25일(금)\r - 내용\r - **Day 17 [프로젝트] 노션 클로닝 요구사항** 확인 부탁드립니다.", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/prgrms-fe-devcourse/FEDC3-4_Project_Notion_VanillaJS.git" + }, + "keywords": [], + "author": "", + "license": "ISC", + "bugs": { + "url": "https://github.com/prgrms-fe-devcourse/FEDC3-4_Project_Notion_VanillaJS/issues" + }, + "homepage": "https://github.com/prgrms-fe-devcourse/FEDC3-4_Project_Notion_VanillaJS#readme", + "devDependencies": { + "prettier": "2.7.1" + }, + "prettier": { + "singleQuote": true, + "semi": true, + "useTabs": false, + "tabWidth": 2, + "trailingComma": "all", + "printWidth": 100, + "bracketSpacing": true, + "arrowParens": "avoid" + } +} diff --git a/src/App.js b/src/App.js new file mode 100644 index 00000000..54aa2da4 --- /dev/null +++ b/src/App.js @@ -0,0 +1,15 @@ +function App({ target }) { + this.route = async () => { + target.innerHTML = ""; + const { pathname } = location; + + if (pathname === "/") { + } else if (pathname.indexOf(`${documentsUrl}/`) === 0) { + const [, , postId] = pathname.split("/"); + } + }; + + this.route(); +} + +export default App; \ No newline at end of file diff --git a/src/style/index.css b/src/style/index.css new file mode 100644 index 00000000..e69de29b diff --git a/src/utils/util.js b/src/utils/util.js new file mode 100644 index 00000000..d0bcec8f --- /dev/null +++ b/src/utils/util.js @@ -0,0 +1,2 @@ +export const documentsUrl = '/documents'; +export const ROUTE_CHANGE_NAME = 'route-change'; From 250e8996ffdb3ddec273acdd7e54c6b39c1bda44 Mon Sep 17 00:00:00 2001 From: Seung-hwan285 Date: Thu, 17 Nov 2022 00:36:05 +0900 Subject: [PATCH 02/29] =?UTF-8?q?chore=20:=20utils=20=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 +- src/utils/api.js | 19 +++++++++++++++++++ src/utils/constant.js | 8 ++++++++ src/utils/dom.js | 5 +++++ src/utils/errorHandler.js | 20 ++++++++++++++++++++ src/utils/route.js | 25 +++++++++++++++++++++++++ 6 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 src/utils/api.js create mode 100644 src/utils/constant.js create mode 100644 src/utils/dom.js create mode 100644 src/utils/errorHandler.js create mode 100644 src/utils/route.js diff --git a/.gitignore b/.gitignore index 6bc83e14..ffcfdbf7 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,7 @@ /package-lock.json /.pnp .pnp.js - +/url.js # intellij configs .idea/ diff --git a/src/utils/api.js b/src/utils/api.js new file mode 100644 index 00000000..8b19030a --- /dev/null +++ b/src/utils/api.js @@ -0,0 +1,19 @@ +import { API_END_POINT } from './apiUrl.js'; + +export const request = async (url, option = {}) => { + try { + const res = await fetch(`${API_END_POINT}${url}`, { + ...option, + headers: { + 'x-username': 'hwa', + 'Content-Type': 'application/json', + }, + }); + + if (res.ok) { + return await res.json(); + } + } catch (e) { + alert(e.message); + } +}; \ No newline at end of file diff --git a/src/utils/constant.js b/src/utils/constant.js new file mode 100644 index 00000000..85d356a2 --- /dev/null +++ b/src/utils/constant.js @@ -0,0 +1,8 @@ +export const ERROR_MESSAGE={ + NEW : 'NEW 연산자가 없습니다.', + Object : '객체 타입이 아닙니다.', + String : '문자열 타입이 아닙니다.' +} + + + diff --git a/src/utils/dom.js b/src/utils/dom.js new file mode 100644 index 00000000..17cd3234 --- /dev/null +++ b/src/utils/dom.js @@ -0,0 +1,5 @@ +export const createElement=(e)=>document.createElement(e); +export const $ =(e)=>document.querySelector(e); +export const targetClosest=(e,str)=>e.target.closest(str); +export const targetContains=(e,str)=>e.target.classList.contains(str); + diff --git a/src/utils/errorHandler.js b/src/utils/errorHandler.js new file mode 100644 index 00000000..8c3ff0cf --- /dev/null +++ b/src/utils/errorHandler.js @@ -0,0 +1,20 @@ +import {ERROR_MESSAGE} from "./constant.js"; + + +export const isNew=(target)=>{ + if(!target){ + throw new Error(ERROR_MESSAGE.NEW); + } +} + +export const isString=(title)=>{ + if(!title instanceof String){ + throw new Error(ERROR_MESSAGE.String); + } +} + +export const isObject=(post)=>{ + if(!post instanceof Object){ + throw new Error(ERROR_MESSAGE.Object); + } +} diff --git a/src/utils/route.js b/src/utils/route.js new file mode 100644 index 00000000..7e9c809c --- /dev/null +++ b/src/utils/route.js @@ -0,0 +1,25 @@ +import {ROUTE_CHANGE_NAME} from "./util.js"; + +export const initRouter = (onRoute) => { + window.addEventListener(ROUTE_CHANGE_NAME, (e) => { + const {nextUrl} = e.detail; + + if(nextUrl) { + history.pushState(null, null, nextUrl); + onRoute(); + } + }); +} + +export const route = (nextUrl) => { + + if(nextUrl){ + window.dispatchEvent(new CustomEvent(ROUTE_CHANGE_NAME, { + detail: { + nextUrl + } + })); + } + +} + From 940d3f85f61e19aeb92cef43d6f3075d164a51d3 Mon Sep 17 00:00:00 2001 From: Seung-hwan285 Date: Thu, 17 Nov 2022 00:41:09 +0900 Subject: [PATCH 03/29] =?UTF-8?q?feat=20:=20Navbar=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 19 +++++++++++--- src/Navbar/DocumentHeader.js | 40 ++++++++++++++++++++++++++++++ src/Navbar/Navbar.js | 32 ++++++++++++++++++++++++ src/utils/api.js | 4 +-- src/utils/constant.js | 10 ++++---- src/utils/errorHandler.js | 33 ++++++++++++------------- src/utils/optionsMethod.js | 48 ++++++++++++++++++++++++++++++++++++ src/utils/route.js | 40 +++++++++++++++--------------- 8 files changed, 178 insertions(+), 48 deletions(-) create mode 100644 src/Navbar/DocumentHeader.js create mode 100644 src/Navbar/Navbar.js create mode 100644 src/utils/optionsMethod.js diff --git a/src/App.js b/src/App.js index 54aa2da4..64d05731 100644 --- a/src/App.js +++ b/src/App.js @@ -1,15 +1,26 @@ +import Navbar from './Navbar/Navbar.js'; +import { documentsUrl } from './utils/util.js'; +import { initRouter } from './utils/route.js'; + function App({ target }) { + const navbarPage = new Navbar({ target }); + this.route = async () => { - target.innerHTML = ""; + target.innerHTML = ''; const { pathname } = location; - if (pathname === "/") { + if (pathname === '/') { + navbarPage.setState(); } else if (pathname.indexOf(`${documentsUrl}/`) === 0) { - const [, , postId] = pathname.split("/"); + const [, , postId] = pathname.split('/'); + + await navbarPage.setState(); + console.log(postId); } }; this.route(); + initRouter(() => this.route()); } -export default App; \ No newline at end of file +export default App; diff --git a/src/Navbar/DocumentHeader.js b/src/Navbar/DocumentHeader.js new file mode 100644 index 00000000..ee7dc0b0 --- /dev/null +++ b/src/Navbar/DocumentHeader.js @@ -0,0 +1,40 @@ +import { createElement, targetClosest } from '../utils/dom.js'; +import { isNew } from '../utils/errorHandler.js'; +import { route } from '../utils/route.js'; +import { documentsUrl } from '../utils/util.js'; +import { addHeaderMethod } from '../utils/optionsMethod.js'; + +function DocumentHeader({ target, initialState }) { + isNew(new.target); + + const header = createElement('div'); + header.className = 'header'; + this.state = initialState; + + this.render = () => { + header.innerHTML = ` + ${this.state.text} + + + + `; + target.appendChild(header); + }; + + // 해당 제목클릭 했을때 page 이동 + const onClickHeader = () => { + header.addEventListener('click', async e => { + const homeBtn = targetClosest(e, '.home-btn'); + if (homeBtn) { + route('/'); + } else { + const createPost = await addHeaderMethod(documentsUrl); + route(`${documentsUrl}/${createPost.id}`); + } + }); + }; + this.render(); + onClickHeader(); +} + +export default DocumentHeader; diff --git a/src/Navbar/Navbar.js b/src/Navbar/Navbar.js new file mode 100644 index 00000000..730002f5 --- /dev/null +++ b/src/Navbar/Navbar.js @@ -0,0 +1,32 @@ +import { isNew } from '../utils/errorHandler.js'; +import { createElement } from '../utils/dom.js'; +import { request } from '../utils/api.js'; +import { documentsUrl } from '../utils/util.js'; +import DocumentHeader from './DocumentHeader.js'; + +function Navbar({ target }) { + isNew(new.target); + const nav = createElement('nav'); + nav.className = 'sidebar'; + + new DocumentHeader({ + target: nav, + initialState: { + text: 'Notion', + button: { + text: '+', + }, + }, + }); + + this.setState = async () => { + const posts = await request(`${documentsUrl}`); + this.render(); + }; + + this.render = async () => { + target.appendChild(nav); + }; +} + +export default Navbar; diff --git a/src/utils/api.js b/src/utils/api.js index 8b19030a..754b0dba 100644 --- a/src/utils/api.js +++ b/src/utils/api.js @@ -1,4 +1,4 @@ -import { API_END_POINT } from './apiUrl.js'; +import { API_END_POINT } from '../../url.js'; export const request = async (url, option = {}) => { try { @@ -16,4 +16,4 @@ export const request = async (url, option = {}) => { } catch (e) { alert(e.message); } -}; \ No newline at end of file +}; diff --git a/src/utils/constant.js b/src/utils/constant.js index 85d356a2..a5c5521e 100644 --- a/src/utils/constant.js +++ b/src/utils/constant.js @@ -1,8 +1,8 @@ -export const ERROR_MESSAGE={ - NEW : 'NEW 연산자가 없습니다.', - Object : '객체 타입이 아닙니다.', - String : '문자열 타입이 아닙니다.' -} +export const ERROR_MESSAGE = { + NEW: 'NEW 연산자가 없습니다.', + Object: '객체 타입이 아닙니다.', + String: '문자열 타입이 아닙니다.', +}; diff --git a/src/utils/errorHandler.js b/src/utils/errorHandler.js index 8c3ff0cf..bde38c62 100644 --- a/src/utils/errorHandler.js +++ b/src/utils/errorHandler.js @@ -1,20 +1,19 @@ -import {ERROR_MESSAGE} from "./constant.js"; +import { ERROR_MESSAGE } from './constant.js'; +export const isNew = target => { + if (!target) { + throw new Error(ERROR_MESSAGE.NEW); + } +}; -export const isNew=(target)=>{ - if(!target){ - throw new Error(ERROR_MESSAGE.NEW); - } -} +export const isString = title => { + if (!title instanceof String) { + throw new Error(ERROR_MESSAGE.String); + } +}; -export const isString=(title)=>{ - if(!title instanceof String){ - throw new Error(ERROR_MESSAGE.String); - } -} - -export const isObject=(post)=>{ - if(!post instanceof Object){ - throw new Error(ERROR_MESSAGE.Object); - } -} +export const isObject = post => { + if (!post instanceof Object) { + throw new Error(ERROR_MESSAGE.Object); + } +}; diff --git a/src/utils/optionsMethod.js b/src/utils/optionsMethod.js new file mode 100644 index 00000000..c3300c86 --- /dev/null +++ b/src/utils/optionsMethod.js @@ -0,0 +1,48 @@ +import {request} from "./api.js"; +import {documentsUrl} from "./util.js"; + +export const putTitleMethod =(id,title)=>{ + return request(`/documents/${id}`,{ + method:'PUT', + body:JSON.stringify({ + title : title, + }), + }); +} + +export const putContentMethod =(id,content)=>{ + return request(`/documents/${id}`,{ + method:'PUT', + body:JSON.stringify({ + content : content, + }), + }); +} + + +export const addMethod = (id) => { + return request('/documents', { + method: 'POST', + body: JSON.stringify({ + title: '', + parent: id + }) + }); + +} + +export const addHeaderMethod =(documentsUrl)=>{ + return request(`${documentsUrl}`,{ + method : 'POST', + boyd: JSON.stringify({ + title:'', + parent : null, + }) + }); +} + +export const deleteMethod = (id) => { + return request(`/documents/${id}`, { + method: 'DELETE' + }); +} diff --git a/src/utils/route.js b/src/utils/route.js index 7e9c809c..a32aeae7 100644 --- a/src/utils/route.js +++ b/src/utils/route.js @@ -1,25 +1,25 @@ -import {ROUTE_CHANGE_NAME} from "./util.js"; +import { ROUTE_CHANGE_NAME } from './util.js'; -export const initRouter = (onRoute) => { - window.addEventListener(ROUTE_CHANGE_NAME, (e) => { - const {nextUrl} = e.detail; +export const initRouter = onRoute => { + window.addEventListener(ROUTE_CHANGE_NAME, e => { + const { nextUrl } = e.detail; - if(nextUrl) { - history.pushState(null, null, nextUrl); - onRoute(); - } - }); -} - -export const route = (nextUrl) => { - - if(nextUrl){ - window.dispatchEvent(new CustomEvent(ROUTE_CHANGE_NAME, { - detail: { - nextUrl - } - })); + if (nextUrl) { + history.pushState(null, null, nextUrl); + onRoute(); } + }); +}; -} +export const route = nextUrl => { + if (nextUrl) { + window.dispatchEvent( + new CustomEvent(ROUTE_CHANGE_NAME, { + detail: { + nextUrl, + }, + }), + ); + } +}; From 137d6360569d5e73724bff8a38f440b9aedf3352 Mon Sep 17 00:00:00 2001 From: Seung-hwan285 Date: Thu, 17 Nov 2022 00:44:10 +0900 Subject: [PATCH 04/29] =?UTF-8?q?style=20:=20Navbar=20css=20=EC=9E=91?= =?UTF-8?q?=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/style/index.css | 138 ++++++++++++++++++++++++++++++++ src/style/ui/index.css | 1 + src/style/ui/modules/navbar.css | 45 +++++++++++ 3 files changed, 184 insertions(+) create mode 100644 src/style/ui/index.css create mode 100644 src/style/ui/modules/navbar.css diff --git a/src/style/index.css b/src/style/index.css index e69de29b..04dce738 100644 --- a/src/style/index.css +++ b/src/style/index.css @@ -0,0 +1,138 @@ +@import 'ui/index.css'; + +/* Reset Browser */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} +html, +body, +div, +span, +applet, +object, +iframe, +h1, +h2, +h3, +h4, +h5, +h6, +p, +blockquote, +pre, +a, +abbr, +acronym, +address, +big, +cite, +code, +del, +dfn, +em, +img, +ins, +kbd, +q, +s, +samp, +small, +strike, +strong, +sub, +sup, +tt, +var, +b, +u, +i, +center, +dl, +dt, +dd, +ol, +fieldset, +form, +label, +legend, +table, +caption, +tbody, +tfoot, +thead, +tr, +th, +td, +article, +aside, +canvas, +details, +embed, +figure, +figcaption, +footer, +header, +hgroup, +menu, +nav, +output, +ruby, +section, +summary, +time, +mark, +audio, +video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; +} + +/* HTML5 display-role reset for browsers */ +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +menu, +nav, +section { + display: block; +} +body { + line-height: 1; +} +ol, +ul { + list-style: none; +} +blockquote, +q { + quotes: none; +} +blockquote:before, +blockquote:after, +q:before, +q:after { + content: ''; + content: none; +} +table { + border-collapse: collapse; + border-spacing: 0; +} +input:focus { + outline: none; +} +a { + color: inherit; + text-decoration: none; +} diff --git a/src/style/ui/index.css b/src/style/ui/index.css new file mode 100644 index 00000000..70964b16 --- /dev/null +++ b/src/style/ui/index.css @@ -0,0 +1 @@ +@import 'modules/navbar.css'; diff --git a/src/style/ui/modules/navbar.css b/src/style/ui/modules/navbar.css new file mode 100644 index 00000000..e9aa3a14 --- /dev/null +++ b/src/style/ui/modules/navbar.css @@ -0,0 +1,45 @@ +.header{ + margin-bottom: 30px; +} + +.document-list{ + padding-left: 10px; +} + +.list-style-type{ + list-style-type: none; +} + +.sidebar{ + width: 20%; + font-size: 15px; + line-height: 1rem; + background-color: rgb(245, 244, 241); + padding: 1em; +} + +.row-item{ + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 5px; + min-height: 27px; + color: #cccbc7; + cursor: pointer; + padding-left: 10px; +} + +.item-text{ + display: flex; + width: 75%; + align-items: center; +} + +.item-button{ + display: flex; + flex-direction: row-reverse; + /*align-items: center;*/ + width: inherit; + /*padding-left: 20px;*/ +} + From 2737c23948c069b80e094f2622c8681389f536f4 Mon Sep 17 00:00:00 2001 From: Seung-hwan285 Date: Thu, 17 Nov 2022 00:50:17 +0900 Subject: [PATCH 05/29] =?UTF-8?q?feat=20:=20Navbar=20documentList=20,=20He?= =?UTF-8?q?ader=20title=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Navbar/DocumentList.js | 70 +++++++++++++++++++++++++++++++++ src/Navbar/Navbar.js | 53 +++++++++++++++++++++++++ src/style/ui/index.css | 1 + src/style/ui/modules/editor.css | 59 +++++++++++++++++++++++++++ 4 files changed, 183 insertions(+) create mode 100644 src/Navbar/DocumentList.js create mode 100644 src/style/ui/modules/editor.css diff --git a/src/Navbar/DocumentList.js b/src/Navbar/DocumentList.js new file mode 100644 index 00000000..36f9f49a --- /dev/null +++ b/src/Navbar/DocumentList.js @@ -0,0 +1,70 @@ +import { createElement, targetClosest, targetContains } from '../utils/dom.js'; +import { isNew } from '../utils/errorHandler.js'; +import { route } from '../utils/route.js'; + +function DocumentList({ target, initialState, onDelete, onAdd }) { + isNew(new.target); + const postList = createElement('div'); + + target.appendChild(postList); + + this.state = initialState; + + this.setState = nextState => { + this.state = nextState; + this.render(); + }; + + this.render = () => { + postList.innerHTML = paintDocument(this.state); + onClickDocument(); + }; + + const paintDocument = docuements => { + return ` +
    + + ${docuements + .map( + post => ` +
  • + +
    + +
    + ${post.title ? post.title : '제목 없음'} +
    + +
    + + +
    +
    + ${post.documents.length ? paintDocument(post.documents) : ''} +
  • + `, + ) + .join('')} +
+ `; + }; + + const onClickDocument = () => { + const ul = postList.querySelector('.document-list'); + + ul.addEventListener('click', e => { + const postId = targetClosest(e, 'li').id; + + if (targetContains(e, 'delete-btn')) { + onDelete(postId); + } else if (targetContains(e, 'add-btn')) { + onAdd(postId); + } else { + route(`/documents/${postId}`); + } + }); + }; + this.render(); +} + +export default DocumentList; diff --git a/src/Navbar/Navbar.js b/src/Navbar/Navbar.js index 730002f5..14a17fd3 100644 --- a/src/Navbar/Navbar.js +++ b/src/Navbar/Navbar.js @@ -3,6 +3,9 @@ import { createElement } from '../utils/dom.js'; import { request } from '../utils/api.js'; import { documentsUrl } from '../utils/util.js'; import DocumentHeader from './DocumentHeader.js'; +import DocumentList from './DocumentList.js'; +import { addMethod, deleteMethod } from '../utils/optionsMethod.js'; +import { route } from '../utils/route.js'; function Navbar({ target }) { isNew(new.target); @@ -19,8 +22,58 @@ function Navbar({ target }) { }, }); + const documentList = new DocumentList({ + target: nav, + initialState: [], + onDelete: async id => { + // 현재 Document 삭제하게 되면 하위 Documents 전부 삭제 + const findCurrentId = () => { + const rootDocument = [...documentList.state]; + + while (rootDocument.length > 0) { + const cur = rootDocument.shift(); + + if (parseInt(cur.id) === parseInt(id)) { + console.log(cur); + return cur; + } + + cur.documents.forEach(el => { + rootDocument.push(el); + }); + } + }; + const handlerDelete = async () => { + const currentDocument = findCurrentId(); + const que = [currentDocument]; + const queId = [currentDocument.id]; + const current = que.shift(); + + while (que.length > 0) { + current.documents.forEach(el => { + que.push(el); + queId.push(el.id); + }); + } + + for (let i of queId) { + await deleteMethod(i); + } + }; + + await handlerDelete(); + route('/'); + }, + + onAdd: async id => { + const newPost = await addMethod(id); + route(`${documentsUrl}/${newPost.id}`); + }, + }); + this.setState = async () => { const posts = await request(`${documentsUrl}`); + documentList.setState(posts); this.render(); }; diff --git a/src/style/ui/index.css b/src/style/ui/index.css index 70964b16..dd48ffe7 100644 --- a/src/style/ui/index.css +++ b/src/style/ui/index.css @@ -1 +1,2 @@ @import 'modules/navbar.css'; +@import 'modules/editor.css'; diff --git a/src/style/ui/modules/editor.css b/src/style/ui/modules/editor.css new file mode 100644 index 00000000..e974ee20 --- /dev/null +++ b/src/style/ui/modules/editor.css @@ -0,0 +1,59 @@ +.app{ + display: flex; + height: 100vh; +} + +button { + border: none; + outline: none; + padding: 0px; + margin: 0px; + background: none; +} + +.content{ + width: 100%; + height: 70%; + border: none; + outline: none; + /*overflow-y: scroll;*/ + font-size: 20px; + display: flex; + justify-content: space-around; + margin-top: 5%; + /*-ms-overflow-style: none;*/ +} + + +.content ::-webkit-scrollbar{ + display: none; + height: 100em; +} + +.editor { + width: 60%; + overflow-y:hidden +} + +.title { + width: 100%; + display: block; + border: none; + outline: none; + font-size: 38px; +} + +.add{ + width: 25px; +} + + + +button { + border: none; + outline: none; + padding: 0; + overflow: hidden; + background: none; + margin-left: 30px; +} From 169014c9180a29f7c69fd3bca731c13f9f19b404 Mon Sep 17 00:00:00 2001 From: Seung-hwan285 Date: Thu, 17 Nov 2022 00:53:55 +0900 Subject: [PATCH 06/29] =?UTF-8?q?feat=20:=20Editor=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 10 ++++++++++ src/Editor/Editor.js | 31 +++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 src/Editor/Editor.js diff --git a/src/App.js b/src/App.js index 64d05731..92301e2a 100644 --- a/src/App.js +++ b/src/App.js @@ -1,9 +1,18 @@ import Navbar from './Navbar/Navbar.js'; import { documentsUrl } from './utils/util.js'; import { initRouter } from './utils/route.js'; +import Editor from './Editor/Editor.js'; function App({ target }) { const navbarPage = new Navbar({ target }); + const postEditPage = new Editor({ + target, + initialState: { + postId: 'new', + title: '', + content: '', + }, + }); this.route = async () => { target.innerHTML = ''; @@ -16,6 +25,7 @@ function App({ target }) { await navbarPage.setState(); console.log(postId); + await postEditPage.setState({ postId }); } }; diff --git a/src/Editor/Editor.js b/src/Editor/Editor.js new file mode 100644 index 00000000..75b528c6 --- /dev/null +++ b/src/Editor/Editor.js @@ -0,0 +1,31 @@ +import { createElement } from '../utils/dom.js'; +import { isObject } from '../utils/errorHandler.js'; +import { request } from '../utils/api.js'; + +function Editor({ target, initialState }) { + const page = createElement('section'); + page.className = 'content'; + + const editor = createElement('div'); + editor.className = 'editor'; + + page.appendChild(editor); + target.appendChild(page); + + this.setState = async nextState => { + console.log(nextState); + + const post = await request(`/documents/${nextState.postId}`); + isObject(post); + + this.render(); + }; + + this.render = () => { + target.appendChild(page); + }; + + this.render(); +} + +export default Editor; From 803bd4f58aeb4ad31a05b9cf1b3c8e3cb7dae5d5 Mon Sep 17 00:00:00 2001 From: Seung-hwan285 Date: Thu, 17 Nov 2022 00:55:34 +0900 Subject: [PATCH 07/29] =?UTF-8?q?feat=20:=20Editor=20title=20=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Editor/Editor.js | 11 ++++++++++ src/Editor/PostTitle.js | 45 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 src/Editor/PostTitle.js diff --git a/src/Editor/Editor.js b/src/Editor/Editor.js index 75b528c6..affd89d3 100644 --- a/src/Editor/Editor.js +++ b/src/Editor/Editor.js @@ -1,6 +1,8 @@ import { createElement } from '../utils/dom.js'; import { isObject } from '../utils/errorHandler.js'; import { request } from '../utils/api.js'; +import PostTitle from './PostTitle.js'; +import { putTitleMethod } from '../utils/optionsMethod.js'; function Editor({ target, initialState }) { const page = createElement('section'); @@ -12,6 +14,15 @@ function Editor({ target, initialState }) { page.appendChild(editor); target.appendChild(page); + const postTitle = new PostTitle({ + div: editor, + initialState: initialState, + + onChangeTitle: async ({ id, title }) => { + setTimeout(await putTitleMethod(id, title), 2000); + }, + }); + this.setState = async nextState => { console.log(nextState); diff --git a/src/Editor/PostTitle.js b/src/Editor/PostTitle.js new file mode 100644 index 00000000..005f16eb --- /dev/null +++ b/src/Editor/PostTitle.js @@ -0,0 +1,45 @@ +import { createElement } from '../utils/dom.js'; +import { isString } from '../utils/errorHandler.js'; + +function PostTitle({ div, initialState, onChangeTitle }) { + const editorTitle = createElement('div'); + this.state = initialState; + + div.appendChild(editorTitle); + + this.setState = nextState => { + this.state = nextState; + // null 나오는게 맞음 헤더 버튼 눌렀을 때 + const { title } = this.state; + let el = $('.title'); + // null 나오는게 맞음 헤더 버튼 눌렀을 때 + this.render(); + editorTitle.querySelector('.title').value = title && title; + }; + + this.render = () => { + const { title } = this.state; + editorTitle.innerHTML = ``; + div.appendChild(editorTitle); + }; + + const onKeyupEditorTitle = () => { + editorTitle.addEventListener('keyup', e => { + const { name } = e.target; + const titleValue = e.target.value; + + isString(titleValue); + + const nextState = { + ...this.state, + [name]: titleValue, + }; + + onChangeTitle(nextState); + }); + }; + this.render(); + onKeyupEditorTitle(); +} + +export default PostTitle; From 89ae913f77ef38dc445d47ba8e104922cb5c6618 Mon Sep 17 00:00:00 2001 From: Seung-hwan285 Date: Thu, 17 Nov 2022 01:00:27 +0900 Subject: [PATCH 08/29] =?UTF-8?q?fix=20:=20title=20=EB=9E=9C=EB=8D=94?= =?UTF-8?q?=EB=A7=81=20=EB=90=A0=EB=95=8C=20=EA=B0=92=20=EC=95=88=EB=B3=80?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=ED=98=84=EC=83=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Editor/Editor.js | 2 +- src/Editor/PostTitle.js | 2 +- src/Navbar/DocumentList.js | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Editor/Editor.js b/src/Editor/Editor.js index affd89d3..47f80ca0 100644 --- a/src/Editor/Editor.js +++ b/src/Editor/Editor.js @@ -28,7 +28,7 @@ function Editor({ target, initialState }) { const post = await request(`/documents/${nextState.postId}`); isObject(post); - + postTitle.setState(post); this.render(); }; diff --git a/src/Editor/PostTitle.js b/src/Editor/PostTitle.js index 005f16eb..38d6d859 100644 --- a/src/Editor/PostTitle.js +++ b/src/Editor/PostTitle.js @@ -1,4 +1,4 @@ -import { createElement } from '../utils/dom.js'; +import { $, createElement } from '../utils/dom.js'; import { isString } from '../utils/errorHandler.js'; function PostTitle({ div, initialState, onChangeTitle }) { diff --git a/src/Navbar/DocumentList.js b/src/Navbar/DocumentList.js index 36f9f49a..c4ca7959 100644 --- a/src/Navbar/DocumentList.js +++ b/src/Navbar/DocumentList.js @@ -60,6 +60,7 @@ function DocumentList({ target, initialState, onDelete, onAdd }) { } else if (targetContains(e, 'add-btn')) { onAdd(postId); } else { + // refactor 해야함 route(`/documents/${postId}`); } }); From 2355c53b8cb41db16e5f3138e17832f45ab423b8 Mon Sep 17 00:00:00 2001 From: Seung-hwan285 Date: Thu, 17 Nov 2022 01:04:07 +0900 Subject: [PATCH 09/29] =?UTF-8?q?feat=20:=20Editor=20Content=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- src/Editor/Editor.js | 15 +++++++++++-- src/Editor/PostContent.js | 46 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 src/Editor/PostContent.js diff --git a/README.md b/README.md index e6b163f8..ca6f8089 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ - [ ] Editor content 부분 textarea 렌더링 했을때 2 개행 이상부터 잘려서 안나오는 현상 - [ ] 버튼 이미지 넣어서 관리 -> 현재 text로 들어가 있음 - [ ] 편집기 하단에는 Documents의 하위 Document 링크를 렌더링하도록 생성 -- [ ] 예외처리 작업 +- [ ] 예외처리 작업, '/documents'-> documentsUrl 변경 - 프로젝트 기한 diff --git a/src/Editor/Editor.js b/src/Editor/Editor.js index 47f80ca0..bb359f19 100644 --- a/src/Editor/Editor.js +++ b/src/Editor/Editor.js @@ -2,7 +2,8 @@ import { createElement } from '../utils/dom.js'; import { isObject } from '../utils/errorHandler.js'; import { request } from '../utils/api.js'; import PostTitle from './PostTitle.js'; -import { putTitleMethod } from '../utils/optionsMethod.js'; +import { putContentMethod, putTitleMethod } from '../utils/optionsMethod.js'; +import PostContent from './PostContent.js'; function Editor({ target, initialState }) { const page = createElement('section'); @@ -23,12 +24,22 @@ function Editor({ target, initialState }) { }, }); + const postContent = new PostContent({ + div: editor, + initialState: initialState, + + onChangeContent: async ({ id, content }) => { + setTimeout(await putContentMethod(id, content), 2000); + }, + }); + this.setState = async nextState => { console.log(nextState); - + // refactor const post = await request(`/documents/${nextState.postId}`); isObject(post); postTitle.setState(post); + postContent.setState(post); this.render(); }; diff --git a/src/Editor/PostContent.js b/src/Editor/PostContent.js new file mode 100644 index 00000000..7cc57775 --- /dev/null +++ b/src/Editor/PostContent.js @@ -0,0 +1,46 @@ +import { createElement } from '../utils/dom.js'; +import { isString } from '../utils/errorHandler.js'; + +function PostContent({ div, initialState, onChangeContent }) { + const editorContent = createElement('div'); + this.state = initialState; + + this.setState = nextState => { + this.state = nextState; + const { content } = this.state; + + this.render(); + editorContent.querySelector('.content').value = content && content; + }; + + this.render = () => { + const { content } = this.state; + + // oninput : textarea Enter 누르면 높이 자동 조절 + editorContent.innerHTML = ``; + + div.appendChild(editorContent); + }; + + const onKeyUpContent = () => { + editorContent.addEventListener('keyup', e => { + const { name } = e.target; + const contentValue = e.target.value; + isString(contentValue); + const nextState = { + ...this.state, + [name]: contentValue, + }; + + onChangeContent(nextState); + }); + }; + onKeyUpContent(); + this.render(); +} + +export default PostContent; From 014ee5fd5cd20efb68de79bd3282e4c40bbfbd53 Mon Sep 17 00:00:00 2001 From: Seung-hwan285 Date: Thu, 17 Nov 2022 01:25:00 +0900 Subject: [PATCH 10/29] =?UTF-8?q?style=20:=20=EA=B8=80=20=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=20,=20=EB=B2=84=ED=8A=BC=20css=20=EC=9E=91=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- src/App.js | 46 +++++++++++----------- src/Editor/PostContent.js | 60 ++++++++++++++-------------- src/Editor/PostTitle.js | 70 ++++++++++++++++----------------- src/Navbar/DocumentHeader.js | 47 +++++++++++----------- src/style/ui/modules/editor.css | 20 ++++++---- src/style/ui/modules/navbar.css | 20 ++++++---- 7 files changed, 136 insertions(+), 129 deletions(-) diff --git a/package.json b/package.json index 76ea3e81..889a13f8 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "singleQuote": true, "semi": true, "useTabs": false, - "tabWidth": 2, + "tabWidth": 4, "trailingComma": "all", "printWidth": 100, "bracketSpacing": true, diff --git a/src/App.js b/src/App.js index 92301e2a..1c8080bd 100644 --- a/src/App.js +++ b/src/App.js @@ -4,33 +4,33 @@ import { initRouter } from './utils/route.js'; import Editor from './Editor/Editor.js'; function App({ target }) { - const navbarPage = new Navbar({ target }); - const postEditPage = new Editor({ - target, - initialState: { - postId: 'new', - title: '', - content: '', - }, - }); + const navbarPage = new Navbar({ target }); + const postEditPage = new Editor({ + target, + initialState: { + postId: 'new', + title: '', + content: '', + }, + }); - this.route = async () => { - target.innerHTML = ''; - const { pathname } = location; + this.route = async () => { + target.innerHTML = ''; + const { pathname } = location; - if (pathname === '/') { - navbarPage.setState(); - } else if (pathname.indexOf(`${documentsUrl}/`) === 0) { - const [, , postId] = pathname.split('/'); + if (pathname === '/') { + navbarPage.setState(); + } else if (pathname.indexOf(`${documentsUrl}/`) === 0) { + const [, , postId] = pathname.split('/'); - await navbarPage.setState(); - console.log(postId); - await postEditPage.setState({ postId }); - } - }; + await navbarPage.setState(); + console.log(postId); + await postEditPage.setState({ postId }); + } + }; - this.route(); - initRouter(() => this.route()); + this.route(); + initRouter(() => this.route()); } export default App; diff --git a/src/Editor/PostContent.js b/src/Editor/PostContent.js index 7cc57775..9f690700 100644 --- a/src/Editor/PostContent.js +++ b/src/Editor/PostContent.js @@ -2,45 +2,45 @@ import { createElement } from '../utils/dom.js'; import { isString } from '../utils/errorHandler.js'; function PostContent({ div, initialState, onChangeContent }) { - const editorContent = createElement('div'); - this.state = initialState; + const editorContent = createElement('div'); + this.state = initialState; - this.setState = nextState => { - this.state = nextState; - const { content } = this.state; + this.setState = nextState => { + this.state = nextState; + const { content } = this.state; - this.render(); - editorContent.querySelector('.content').value = content && content; - }; + this.render(); + editorContent.querySelector('.content').value = content && content; + }; - this.render = () => { - const { content } = this.state; + this.render = () => { + const { content } = this.state; - // oninput : textarea Enter 누르면 높이 자동 조절 - editorContent.innerHTML = ``; - div.appendChild(editorContent); - }; - - const onKeyUpContent = () => { - editorContent.addEventListener('keyup', e => { - const { name } = e.target; - const contentValue = e.target.value; - isString(contentValue); - const nextState = { - ...this.state, - [name]: contentValue, - }; - - onChangeContent(nextState); - }); - }; - onKeyUpContent(); - this.render(); + div.appendChild(editorContent); + }; + + const onKeyUpContent = () => { + editorContent.addEventListener('keyup', e => { + const { name } = e.target; + const contentValue = e.target.value; + isString(contentValue); + const nextState = { + ...this.state, + [name]: contentValue, + }; + + onChangeContent(nextState); + }); + }; + onKeyUpContent(); + this.render(); } export default PostContent; diff --git a/src/Editor/PostTitle.js b/src/Editor/PostTitle.js index 38d6d859..340eaf80 100644 --- a/src/Editor/PostTitle.js +++ b/src/Editor/PostTitle.js @@ -2,44 +2,44 @@ import { $, createElement } from '../utils/dom.js'; import { isString } from '../utils/errorHandler.js'; function PostTitle({ div, initialState, onChangeTitle }) { - const editorTitle = createElement('div'); - this.state = initialState; + const editorTitle = createElement('div'); + this.state = initialState; - div.appendChild(editorTitle); - - this.setState = nextState => { - this.state = nextState; - // null 나오는게 맞음 헤더 버튼 눌렀을 때 - const { title } = this.state; - let el = $('.title'); - // null 나오는게 맞음 헤더 버튼 눌렀을 때 - this.render(); - editorTitle.querySelector('.title').value = title && title; - }; - - this.render = () => { - const { title } = this.state; - editorTitle.innerHTML = ``; div.appendChild(editorTitle); - }; - - const onKeyupEditorTitle = () => { - editorTitle.addEventListener('keyup', e => { - const { name } = e.target; - const titleValue = e.target.value; - isString(titleValue); - - const nextState = { - ...this.state, - [name]: titleValue, - }; - - onChangeTitle(nextState); - }); - }; - this.render(); - onKeyupEditorTitle(); + this.setState = nextState => { + this.state = nextState; + // null 나오는게 맞음 헤더 버튼 눌렀을 때 + const { title } = this.state; + let el = $('.title'); + // null 나오는게 맞음 헤더 버튼 눌렀을 때 + this.render(); + editorTitle.querySelector('.title').value = title && title; + }; + + this.render = () => { + const { title } = this.state; + editorTitle.innerHTML = ``; + div.appendChild(editorTitle); + }; + + const onKeyupEditorTitle = () => { + editorTitle.addEventListener('keyup', e => { + const { name } = e.target; + const titleValue = e.target.value; + + isString(titleValue); + + const nextState = { + ...this.state, + [name]: titleValue, + }; + + onChangeTitle(nextState); + }); + }; + this.render(); + onKeyupEditorTitle(); } export default PostTitle; diff --git a/src/Navbar/DocumentHeader.js b/src/Navbar/DocumentHeader.js index ee7dc0b0..a77702ab 100644 --- a/src/Navbar/DocumentHeader.js +++ b/src/Navbar/DocumentHeader.js @@ -5,36 +5,35 @@ import { documentsUrl } from '../utils/util.js'; import { addHeaderMethod } from '../utils/optionsMethod.js'; function DocumentHeader({ target, initialState }) { - isNew(new.target); + isNew(new.target); - const header = createElement('div'); - header.className = 'header'; - this.state = initialState; + const header = createElement('div'); + header.className = 'header'; + this.state = initialState; - this.render = () => { - header.innerHTML = ` + this.render = () => { + header.innerHTML = ` ${this.state.text} - - + `; - target.appendChild(header); - }; + target.appendChild(header); + }; - // 해당 제목클릭 했을때 page 이동 - const onClickHeader = () => { - header.addEventListener('click', async e => { - const homeBtn = targetClosest(e, '.home-btn'); - if (homeBtn) { - route('/'); - } else { - const createPost = await addHeaderMethod(documentsUrl); - route(`${documentsUrl}/${createPost.id}`); - } - }); - }; - this.render(); - onClickHeader(); + // 해당 제목클릭 했을때 page 이동 + const onClickHeader = () => { + header.addEventListener('click', async e => { + const homeBtn = targetClosest(e, '.home-btn'); + if (homeBtn) { + route('/'); + } else { + const createPost = await addHeaderMethod(documentsUrl); + route(`${documentsUrl}/${createPost.id}`); + } + }); + }; + this.render(); + onClickHeader(); } export default DocumentHeader; diff --git a/src/style/ui/modules/editor.css b/src/style/ui/modules/editor.css index e974ee20..ea68f7d9 100644 --- a/src/style/ui/modules/editor.css +++ b/src/style/ui/modules/editor.css @@ -1,4 +1,4 @@ -.app{ +.app { display: flex; height: 100vh; } @@ -11,7 +11,7 @@ button { background: none; } -.content{ +.content { width: 100%; height: 70%; border: none; @@ -24,15 +24,14 @@ button { /*-ms-overflow-style: none;*/ } - -.content ::-webkit-scrollbar{ +.content ::-webkit-scrollbar { display: none; height: 100em; } .editor { width: 60%; - overflow-y:hidden + overflow-y: hidden; } .title { @@ -43,12 +42,10 @@ button { font-size: 38px; } -.add{ +.add { width: 25px; } - - button { border: none; outline: none; @@ -56,4 +53,11 @@ button { overflow: hidden; background: none; margin-left: 30px; + cursor: pointer; +} + +button:hover { + border: solid 1px #aca99e; + border-radius: 5px; + color: black; } diff --git a/src/style/ui/modules/navbar.css b/src/style/ui/modules/navbar.css index e9aa3a14..a14c81f6 100644 --- a/src/style/ui/modules/navbar.css +++ b/src/style/ui/modules/navbar.css @@ -1,16 +1,16 @@ -.header{ +.header { margin-bottom: 30px; } -.document-list{ +.document-list { padding-left: 10px; } -.list-style-type{ +.list-style-type { list-style-type: none; } -.sidebar{ +.sidebar { width: 20%; font-size: 15px; line-height: 1rem; @@ -18,7 +18,7 @@ padding: 1em; } -.row-item{ +.row-item { display: flex; justify-content: space-between; align-items: center; @@ -29,17 +29,21 @@ padding-left: 10px; } -.item-text{ +.row-item:hover { + background: rgba(55, 53, 47, 0.08); + color: black; +} + +.item-text { display: flex; width: 75%; align-items: center; } -.item-button{ +.item-button { display: flex; flex-direction: row-reverse; /*align-items: center;*/ width: inherit; /*padding-left: 20px;*/ } - From 74b5a86a82837e5955d68d5962db2737f595f529 Mon Sep 17 00:00:00 2001 From: Seung-hwan285 Date: Thu, 17 Nov 2022 01:34:40 +0900 Subject: [PATCH 11/29] =?UTF-8?q?refactor=20:=20editor.css=20=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EB=91=90=EB=B2=88=20?= =?UTF-8?q?=EC=84=A0=EC=96=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- src/Editor/Editor.js | 78 ++++++++++---------- src/Editor/PostContent.js | 4 +- src/Editor/PostTitle.js | 4 +- src/Navbar/DocumentHeader.js | 3 +- src/Navbar/DocumentList.js | 68 +++++++++--------- src/Navbar/Navbar.js | 122 ++++++++++++++++---------------- src/style/ui/modules/editor.css | 8 --- src/style/ui/modules/navbar.css | 8 +++ 9 files changed, 149 insertions(+), 148 deletions(-) diff --git a/package.json b/package.json index 889a13f8..7a7ab43f 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,6 @@ "trailingComma": "all", "printWidth": 100, "bracketSpacing": true, - "arrowParens": "avoid" + "arrowParens": "always" } } diff --git a/src/Editor/Editor.js b/src/Editor/Editor.js index bb359f19..f07aa53a 100644 --- a/src/Editor/Editor.js +++ b/src/Editor/Editor.js @@ -6,48 +6,48 @@ import { putContentMethod, putTitleMethod } from '../utils/optionsMethod.js'; import PostContent from './PostContent.js'; function Editor({ target, initialState }) { - const page = createElement('section'); - page.className = 'content'; - - const editor = createElement('div'); - editor.className = 'editor'; - - page.appendChild(editor); - target.appendChild(page); - - const postTitle = new PostTitle({ - div: editor, - initialState: initialState, - - onChangeTitle: async ({ id, title }) => { - setTimeout(await putTitleMethod(id, title), 2000); - }, - }); - - const postContent = new PostContent({ - div: editor, - initialState: initialState, - - onChangeContent: async ({ id, content }) => { - setTimeout(await putContentMethod(id, content), 2000); - }, - }); - - this.setState = async nextState => { - console.log(nextState); - // refactor - const post = await request(`/documents/${nextState.postId}`); - isObject(post); - postTitle.setState(post); - postContent.setState(post); - this.render(); - }; + const page = createElement('section'); + page.className = 'content'; + + const editor = createElement('div'); + editor.className = 'editor'; - this.render = () => { + page.appendChild(editor); target.appendChild(page); - }; - this.render(); + const postTitle = new PostTitle({ + div: editor, + initialState: initialState, + + onChangeTitle: async ({ id, title }) => { + setTimeout(await putTitleMethod(id, title), 2000); + }, + }); + + const postContent = new PostContent({ + div: editor, + initialState: initialState, + + onChangeContent: async ({ id, content }) => { + setTimeout(await putContentMethod(id, content), 2000); + }, + }); + + this.setState = async (nextState) => { + console.log(nextState); + // refactor + const post = await request(`/documents/${nextState.postId}`); + isObject(post); + postTitle.setState(post); + postContent.setState(post); + this.render(); + }; + + this.render = () => { + target.appendChild(page); + }; + + this.render(); } export default Editor; diff --git a/src/Editor/PostContent.js b/src/Editor/PostContent.js index 9f690700..d995806b 100644 --- a/src/Editor/PostContent.js +++ b/src/Editor/PostContent.js @@ -5,7 +5,7 @@ function PostContent({ div, initialState, onChangeContent }) { const editorContent = createElement('div'); this.state = initialState; - this.setState = nextState => { + this.setState = (nextState) => { this.state = nextState; const { content } = this.state; @@ -27,7 +27,7 @@ function PostContent({ div, initialState, onChangeContent }) { }; const onKeyUpContent = () => { - editorContent.addEventListener('keyup', e => { + editorContent.addEventListener('keyup', (e) => { const { name } = e.target; const contentValue = e.target.value; isString(contentValue); diff --git a/src/Editor/PostTitle.js b/src/Editor/PostTitle.js index 340eaf80..b7edfb93 100644 --- a/src/Editor/PostTitle.js +++ b/src/Editor/PostTitle.js @@ -7,7 +7,7 @@ function PostTitle({ div, initialState, onChangeTitle }) { div.appendChild(editorTitle); - this.setState = nextState => { + this.setState = (nextState) => { this.state = nextState; // null 나오는게 맞음 헤더 버튼 눌렀을 때 const { title } = this.state; @@ -24,7 +24,7 @@ function PostTitle({ div, initialState, onChangeTitle }) { }; const onKeyupEditorTitle = () => { - editorTitle.addEventListener('keyup', e => { + editorTitle.addEventListener('keyup', (e) => { const { name } = e.target; const titleValue = e.target.value; diff --git a/src/Navbar/DocumentHeader.js b/src/Navbar/DocumentHeader.js index a77702ab..48225b70 100644 --- a/src/Navbar/DocumentHeader.js +++ b/src/Navbar/DocumentHeader.js @@ -22,7 +22,7 @@ function DocumentHeader({ target, initialState }) { // 해당 제목클릭 했을때 page 이동 const onClickHeader = () => { - header.addEventListener('click', async e => { + header.addEventListener('click', async (e) => { const homeBtn = targetClosest(e, '.home-btn'); if (homeBtn) { route('/'); @@ -33,6 +33,7 @@ function DocumentHeader({ target, initialState }) { }); }; this.render(); + onClickHeader(); } diff --git a/src/Navbar/DocumentList.js b/src/Navbar/DocumentList.js index c4ca7959..6e59bae2 100644 --- a/src/Navbar/DocumentList.js +++ b/src/Navbar/DocumentList.js @@ -3,30 +3,30 @@ import { isNew } from '../utils/errorHandler.js'; import { route } from '../utils/route.js'; function DocumentList({ target, initialState, onDelete, onAdd }) { - isNew(new.target); - const postList = createElement('div'); + isNew(new.target); + const postList = createElement('div'); - target.appendChild(postList); + target.appendChild(postList); - this.state = initialState; + this.state = initialState; - this.setState = nextState => { - this.state = nextState; - this.render(); - }; + this.setState = (nextState) => { + this.state = nextState; + this.render(); + }; - this.render = () => { - postList.innerHTML = paintDocument(this.state); - onClickDocument(); - }; + this.render = () => { + postList.innerHTML = paintDocument(this.state); + onClickDocument(); + }; - const paintDocument = docuements => { - return ` + const paintDocument = (docuements) => { + return `
    ${docuements - .map( - post => ` + .map( + (post) => `
  • @@ -43,29 +43,29 @@ function DocumentList({ target, initialState, onDelete, onAdd }) { ${post.documents.length ? paintDocument(post.documents) : ''}
  • `, - ) - .join('')} + ) + .join('')}
`; - }; + }; - const onClickDocument = () => { - const ul = postList.querySelector('.document-list'); + const onClickDocument = () => { + const ul = postList.querySelector('.document-list'); - ul.addEventListener('click', e => { - const postId = targetClosest(e, 'li').id; + ul.addEventListener('click', (e) => { + const postId = targetClosest(e, 'li').id; - if (targetContains(e, 'delete-btn')) { - onDelete(postId); - } else if (targetContains(e, 'add-btn')) { - onAdd(postId); - } else { - // refactor 해야함 - route(`/documents/${postId}`); - } - }); - }; - this.render(); + if (targetContains(e, 'delete-btn')) { + onDelete(postId); + } else if (targetContains(e, 'add-btn')) { + onAdd(postId); + } else { + // refactor 해야함 + route(`/documents/${postId}`); + } + }); + }; + this.render(); } export default DocumentList; diff --git a/src/Navbar/Navbar.js b/src/Navbar/Navbar.js index 14a17fd3..066ea522 100644 --- a/src/Navbar/Navbar.js +++ b/src/Navbar/Navbar.js @@ -8,78 +8,78 @@ import { addMethod, deleteMethod } from '../utils/optionsMethod.js'; import { route } from '../utils/route.js'; function Navbar({ target }) { - isNew(new.target); - const nav = createElement('nav'); - nav.className = 'sidebar'; + isNew(new.target); + const nav = createElement('nav'); + nav.className = 'sidebar'; - new DocumentHeader({ - target: nav, - initialState: { - text: 'Notion', - button: { - text: '+', - }, - }, - }); + new DocumentHeader({ + target: nav, + initialState: { + text: 'Notion', + button: { + text: '+', + }, + }, + }); - const documentList = new DocumentList({ - target: nav, - initialState: [], - onDelete: async id => { - // 현재 Document 삭제하게 되면 하위 Documents 전부 삭제 - const findCurrentId = () => { - const rootDocument = [...documentList.state]; + const documentList = new DocumentList({ + target: nav, + initialState: [], + onDelete: async (id) => { + // 현재 Document 삭제하게 되면 하위 Documents 전부 삭제 + const findCurrentId = () => { + const rootDocument = [...documentList.state]; - while (rootDocument.length > 0) { - const cur = rootDocument.shift(); + while (rootDocument.length > 0) { + const cur = rootDocument.shift(); - if (parseInt(cur.id) === parseInt(id)) { - console.log(cur); - return cur; - } + if (parseInt(cur.id) === parseInt(id)) { + console.log(cur); + return cur; + } - cur.documents.forEach(el => { - rootDocument.push(el); - }); - } - }; - const handlerDelete = async () => { - const currentDocument = findCurrentId(); - const que = [currentDocument]; - const queId = [currentDocument.id]; - const current = que.shift(); + cur.documents.forEach((el) => { + rootDocument.push(el); + }); + } + }; + const handlerDelete = async () => { + const currentDocument = findCurrentId(); + const que = [currentDocument]; + const queId = [currentDocument.id]; + const current = que.shift(); - while (que.length > 0) { - current.documents.forEach(el => { - que.push(el); - queId.push(el.id); - }); - } + while (que.length > 0) { + current.documents.forEach((el) => { + que.push(el); + queId.push(el.id); + }); + } - for (let i of queId) { - await deleteMethod(i); - } - }; + for (let i of queId) { + await deleteMethod(i); + } + }; - await handlerDelete(); - route('/'); - }, + await handlerDelete(); + route('/'); + }, - onAdd: async id => { - const newPost = await addMethod(id); - route(`${documentsUrl}/${newPost.id}`); - }, - }); + onAdd: async (id) => { + const newPost = await addMethod(id); + route(`${documentsUrl}/${newPost.id}`); + }, + }); - this.setState = async () => { - const posts = await request(`${documentsUrl}`); - documentList.setState(posts); - this.render(); - }; + this.setState = async () => { + const posts = await request(`${documentsUrl}`); + documentList.setState(posts); + this.render(); + }; - this.render = async () => { - target.appendChild(nav); - }; + this.render = async () => { + target.appendChild(nav); + }; } export default Navbar; diff --git a/src/style/ui/modules/editor.css b/src/style/ui/modules/editor.css index ea68f7d9..ccbb82e4 100644 --- a/src/style/ui/modules/editor.css +++ b/src/style/ui/modules/editor.css @@ -3,14 +3,6 @@ height: 100vh; } -button { - border: none; - outline: none; - padding: 0px; - margin: 0px; - background: none; -} - .content { width: 100%; height: 70%; diff --git a/src/style/ui/modules/navbar.css b/src/style/ui/modules/navbar.css index a14c81f6..d04d19f2 100644 --- a/src/style/ui/modules/navbar.css +++ b/src/style/ui/modules/navbar.css @@ -47,3 +47,11 @@ width: inherit; /*padding-left: 20px;*/ } + +.delete-btn { + font-size: 18px; +} + +.add-btn { + font-size: 18px; +} From 409269cccb53c0bc55c4fd859e532264c8757d23 Mon Sep 17 00:00:00 2001 From: Seung-hwan285 Date: Thu, 17 Nov 2022 01:51:58 +0900 Subject: [PATCH 12/29] =?UTF-8?q?refactor:=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20=EB=84=A4=EC=9D=B4=EB=B0=8D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 1 - src/Editor/Editor.js | 8 +++---- .../{PostContent.js => EditorContent.js} | 4 ++-- src/Editor/{PostTitle.js => EditorTitle.js} | 4 ++-- src/Navbar/Navbar.js | 9 +++---- ...{DocumentList.js => NavbarDocumentList.js} | 4 ++-- .../{DocumentHeader.js => NavbarHeader.js} | 4 ++-- src/utils/constant.js | 9 +++---- src/utils/errorHandler.js | 24 +++++++++---------- 9 files changed, 32 insertions(+), 35 deletions(-) rename src/Editor/{PostContent.js => EditorContent.js} (92%) rename src/Editor/{PostTitle.js => EditorTitle.js} (93%) rename src/Navbar/{DocumentList.js => NavbarDocumentList.js} (94%) rename src/Navbar/{DocumentHeader.js => NavbarHeader.js} (93%) diff --git a/src/App.js b/src/App.js index 1c8080bd..25a3f241 100644 --- a/src/App.js +++ b/src/App.js @@ -24,7 +24,6 @@ function App({ target }) { const [, , postId] = pathname.split('/'); await navbarPage.setState(); - console.log(postId); await postEditPage.setState({ postId }); } }; diff --git a/src/Editor/Editor.js b/src/Editor/Editor.js index f07aa53a..bb77a363 100644 --- a/src/Editor/Editor.js +++ b/src/Editor/Editor.js @@ -1,9 +1,9 @@ import { createElement } from '../utils/dom.js'; import { isObject } from '../utils/errorHandler.js'; import { request } from '../utils/api.js'; -import PostTitle from './PostTitle.js'; import { putContentMethod, putTitleMethod } from '../utils/optionsMethod.js'; -import PostContent from './PostContent.js'; +import EditorTitle from './EditorTitle.js'; +import EditorContent from './EditorContent.js'; function Editor({ target, initialState }) { const page = createElement('section'); @@ -15,7 +15,7 @@ function Editor({ target, initialState }) { page.appendChild(editor); target.appendChild(page); - const postTitle = new PostTitle({ + const postTitle = new EditorTitle({ div: editor, initialState: initialState, @@ -24,7 +24,7 @@ function Editor({ target, initialState }) { }, }); - const postContent = new PostContent({ + const postContent = new EditorContent({ div: editor, initialState: initialState, diff --git a/src/Editor/PostContent.js b/src/Editor/EditorContent.js similarity index 92% rename from src/Editor/PostContent.js rename to src/Editor/EditorContent.js index d995806b..06a87783 100644 --- a/src/Editor/PostContent.js +++ b/src/Editor/EditorContent.js @@ -1,7 +1,7 @@ import { createElement } from '../utils/dom.js'; import { isString } from '../utils/errorHandler.js'; -function PostContent({ div, initialState, onChangeContent }) { +function EditorContent({ div, initialState, onChangeContent }) { const editorContent = createElement('div'); this.state = initialState; @@ -43,4 +43,4 @@ function PostContent({ div, initialState, onChangeContent }) { this.render(); } -export default PostContent; +export default EditorContent; diff --git a/src/Editor/PostTitle.js b/src/Editor/EditorTitle.js similarity index 93% rename from src/Editor/PostTitle.js rename to src/Editor/EditorTitle.js index b7edfb93..0a2f05d6 100644 --- a/src/Editor/PostTitle.js +++ b/src/Editor/EditorTitle.js @@ -1,7 +1,7 @@ import { $, createElement } from '../utils/dom.js'; import { isString } from '../utils/errorHandler.js'; -function PostTitle({ div, initialState, onChangeTitle }) { +function EditorTitle({ div, initialState, onChangeTitle }) { const editorTitle = createElement('div'); this.state = initialState; @@ -42,4 +42,4 @@ function PostTitle({ div, initialState, onChangeTitle }) { onKeyupEditorTitle(); } -export default PostTitle; +export default EditorTitle; diff --git a/src/Navbar/Navbar.js b/src/Navbar/Navbar.js index 066ea522..d64fe287 100644 --- a/src/Navbar/Navbar.js +++ b/src/Navbar/Navbar.js @@ -2,17 +2,18 @@ import { isNew } from '../utils/errorHandler.js'; import { createElement } from '../utils/dom.js'; import { request } from '../utils/api.js'; import { documentsUrl } from '../utils/util.js'; -import DocumentHeader from './DocumentHeader.js'; -import DocumentList from './DocumentList.js'; + import { addMethod, deleteMethod } from '../utils/optionsMethod.js'; import { route } from '../utils/route.js'; +import NavbarDocumentList from './NavbarDocumentList.js'; +import NavbarHeader from './NavbarHeader.js'; function Navbar({ target }) { isNew(new.target); const nav = createElement('nav'); nav.className = 'sidebar'; - new DocumentHeader({ + new NavbarHeader({ target: nav, initialState: { text: 'Notion', @@ -22,7 +23,7 @@ function Navbar({ target }) { }, }); - const documentList = new DocumentList({ + const documentList = new NavbarDocumentList({ target: nav, initialState: [], onDelete: async (id) => { diff --git a/src/Navbar/DocumentList.js b/src/Navbar/NavbarDocumentList.js similarity index 94% rename from src/Navbar/DocumentList.js rename to src/Navbar/NavbarDocumentList.js index 6e59bae2..e475b96a 100644 --- a/src/Navbar/DocumentList.js +++ b/src/Navbar/NavbarDocumentList.js @@ -2,7 +2,7 @@ import { createElement, targetClosest, targetContains } from '../utils/dom.js'; import { isNew } from '../utils/errorHandler.js'; import { route } from '../utils/route.js'; -function DocumentList({ target, initialState, onDelete, onAdd }) { +function NavbarDocumentList({ target, initialState, onDelete, onAdd }) { isNew(new.target); const postList = createElement('div'); @@ -68,4 +68,4 @@ function DocumentList({ target, initialState, onDelete, onAdd }) { this.render(); } -export default DocumentList; +export default NavbarDocumentList; diff --git a/src/Navbar/DocumentHeader.js b/src/Navbar/NavbarHeader.js similarity index 93% rename from src/Navbar/DocumentHeader.js rename to src/Navbar/NavbarHeader.js index 48225b70..92c78b0f 100644 --- a/src/Navbar/DocumentHeader.js +++ b/src/Navbar/NavbarHeader.js @@ -4,7 +4,7 @@ import { route } from '../utils/route.js'; import { documentsUrl } from '../utils/util.js'; import { addHeaderMethod } from '../utils/optionsMethod.js'; -function DocumentHeader({ target, initialState }) { +function NavbarHeader({ target, initialState }) { isNew(new.target); const header = createElement('div'); @@ -37,4 +37,4 @@ function DocumentHeader({ target, initialState }) { onClickHeader(); } -export default DocumentHeader; +export default NavbarHeader; diff --git a/src/utils/constant.js b/src/utils/constant.js index a5c5521e..ac58093b 100644 --- a/src/utils/constant.js +++ b/src/utils/constant.js @@ -1,8 +1,5 @@ export const ERROR_MESSAGE = { - NEW: 'NEW 연산자가 없습니다.', - Object: '객체 타입이 아닙니다.', - String: '문자열 타입이 아닙니다.', + NEW: 'NEW 연산자가 없습니다.', + OBJECT: '객체 타입이 아닙니다.', + STRING: '문자열 타입이 아닙니다.', }; - - - diff --git a/src/utils/errorHandler.js b/src/utils/errorHandler.js index bde38c62..682bfbec 100644 --- a/src/utils/errorHandler.js +++ b/src/utils/errorHandler.js @@ -1,19 +1,19 @@ import { ERROR_MESSAGE } from './constant.js'; -export const isNew = target => { - if (!target) { - throw new Error(ERROR_MESSAGE.NEW); - } +export const isNew = (target) => { + if (!target) { + throw new Error(ERROR_MESSAGE.NEW); + } }; -export const isString = title => { - if (!title instanceof String) { - throw new Error(ERROR_MESSAGE.String); - } +export const isString = (title) => { + if (!title instanceof String) { + throw new Error(ERROR_MESSAGE.STRING); + } }; -export const isObject = post => { - if (!post instanceof Object) { - throw new Error(ERROR_MESSAGE.Object); - } +export const isObject = (post) => { + if (!post instanceof Object) { + throw new Error(ERROR_MESSAGE.OBJECT); + } }; From c317732256e011eeeda8ce2f01f0d23afd650371 Mon Sep 17 00:00:00 2001 From: Seung-hwan285 Date: Thu, 17 Nov 2022 02:16:33 +0900 Subject: [PATCH 13/29] =?UTF-8?q?fix=20:=20document=20=EC=A0=84=EB=B6=80?= =?UTF-8?q?=20=EC=82=AD=EC=A0=9C=20=EC=95=88=EB=90=98=EB=8A=94=20=ED=98=84?= =?UTF-8?q?=EC=83=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 7 ++++--- src/Navbar/Navbar.js | 15 +++++++++++---- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index ca6f8089..f9b24b1a 100644 --- a/README.md +++ b/README.md @@ -10,13 +10,14 @@ - [x] 편집기에는 기본적으로 저장 버튼이 없습니다. Document Save API를 이용해 지속적으로 서버에 저장되도록 합니다. - [x] History API를 이용해 SPA형태로 만듭니다. - [x] 루트 URL 접속 시엔 별다른 편집기 선택이 안된 상태입니다. -- [x] /documents/{documentId} 로 접속시 , 해당 Document의 content를 불러와 편집기에 로딩합니다. -- [x] Header 버튼 클릭하면 정상적으로 새로운 Document가 생성되는데 초기값 null 들어가는 현상 +- [x] /documents/{documentId} 로 접속시 , 해당 Document content를 불러와 편집기에 로딩합니다. +- [x] Header 버튼 클릭하면 정상적으로 새로운 Document 생성되는데 초기값 null 들어가는 현상 - [x] '제목없음' ,'내용없음' 초기에 grey color , input 들어오면 색 변경 - [x] putMethod 404 Error - [x] Editor content 부분 textarea 값 변경 안되는 현상 - [x] Editor content 부분 입력할때 textarea 2 개행 이상부터 안보이는 현상 -- [x] 상위 Document 삭제하면 하위 Document도 같이 삭제가 되야 하는데 상위 Document 밑으로 이동 되는 현상 +- [x] 상위 Document 삭제하면 하위 Document 같이 삭제가 되야 하는데 상위 Document 밑으로 이동 되는 현상 +- [ ] 상위 Document 삭제하면 최하위 Document 삭제 안되는 현상 - [ ] Editor content 부분 textarea 렌더링 했을때 2 개행 이상부터 잘려서 안나오는 현상 - [ ] 버튼 이미지 넣어서 관리 -> 현재 text로 들어가 있음 - [ ] 편집기 하단에는 Documents의 하위 Document 링크를 렌더링하도록 생성 diff --git a/src/Navbar/Navbar.js b/src/Navbar/Navbar.js index d64fe287..47273f31 100644 --- a/src/Navbar/Navbar.js +++ b/src/Navbar/Navbar.js @@ -44,21 +44,28 @@ function Navbar({ target }) { }); } }; + + // 현재 하위 document 가 3개 이상이면 하위 document 값이 삭제가 안되고 있음 + // 하위 document 2개씩만 삭제되는 현상 const handlerDelete = async () => { const currentDocument = findCurrentId(); + const que = [currentDocument]; + + console.log(que); const queId = [currentDocument.id]; - const current = que.shift(); while (que.length > 0) { + const current = que.shift(); current.documents.forEach((el) => { que.push(el); queId.push(el.id); }); - } - for (let i of queId) { - await deleteMethod(i); + for (let i of queId) { + console.log(i); + await deleteMethod(i); + } } }; From f55b762c9b942dd9c94ccb29cd9a0a3a472c6122 Mon Sep 17 00:00:00 2001 From: Seung-hwan285 Date: Thu, 17 Nov 2022 02:17:48 +0900 Subject: [PATCH 14/29] =?UTF-8?q?docs=20:=20README=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f9b24b1a..9c2fe18b 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ - [x] Editor content 부분 textarea 값 변경 안되는 현상 - [x] Editor content 부분 입력할때 textarea 2 개행 이상부터 안보이는 현상 - [x] 상위 Document 삭제하면 하위 Document 같이 삭제가 되야 하는데 상위 Document 밑으로 이동 되는 현상 -- [ ] 상위 Document 삭제하면 최하위 Document 삭제 안되는 현상 +- [x] 상위 Document 삭제하면 최하위 Document 삭제 안되는 현상 - [ ] Editor content 부분 textarea 렌더링 했을때 2 개행 이상부터 잘려서 안나오는 현상 - [ ] 버튼 이미지 넣어서 관리 -> 현재 text로 들어가 있음 - [ ] 편집기 하단에는 Documents의 하위 Document 링크를 렌더링하도록 생성 From bb3acae5b99345248387ea222025253c9c3ef323 Mon Sep 17 00:00:00 2001 From: Seung-hwan285 Date: Thu, 17 Nov 2022 02:51:09 +0900 Subject: [PATCH 15/29] =?UTF-8?q?fix:=20=EB=A0=8C=EB=8D=94=EB=A7=81=20?= =?UTF-8?q?=ED=95=98=EB=A9=B4=202=EA=B0=9C=ED=96=89=20=EC=9D=B4=EC=83=81?= =?UTF-8?q?=EB=B6=80=ED=84=B0=20=EC=95=88=EB=B3=B4=EC=9D=B4=EB=8A=94=20?= =?UTF-8?q?=ED=98=84=EC=83=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 7 ++-- src/Editor/Editor.js | 3 +- src/Editor/EditorContent.js | 1 + src/Editor/EditorTitle.js | 1 + src/Navbar/Navbar.js | 2 -- src/Navbar/NavbarDocumentList.js | 3 +- src/style/ui/modules/editor.css | 8 +++++ src/utils/optionsMethod.js | 60 +++++++++++++++----------------- 8 files changed, 47 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index 9c2fe18b..1883abf9 100644 --- a/README.md +++ b/README.md @@ -18,11 +18,12 @@ - [x] Editor content 부분 입력할때 textarea 2 개행 이상부터 안보이는 현상 - [x] 상위 Document 삭제하면 하위 Document 같이 삭제가 되야 하는데 상위 Document 밑으로 이동 되는 현상 - [x] 상위 Document 삭제하면 최하위 Document 삭제 안되는 현상 -- [ ] Editor content 부분 textarea 렌더링 했을때 2 개행 이상부터 잘려서 안나오는 현상 +- [x] 예외처리 작업, '/documents'-> documentsUrl 변경 +- [x] Editor content 부분 textarea 렌더링 했을때 2 개행 이상부터 잘려서 안나오는 현상 - [ ] 버튼 이미지 넣어서 관리 -> 현재 text로 들어가 있음 - [ ] 편집기 하단에는 Documents의 하위 Document 링크를 렌더링하도록 생성 -- [ ] 예외처리 작업, '/documents'-> documentsUrl 변경 - +- [ ] onDelete 리팩토링 필요 +- [ ] 정상적으로 삭제 기능 동작, Delete 404 에러 나오고있음 -> 물어보기 - 프로젝트 기한 - 프로젝트 수행 기간 : 2022년 11월 8일(화) ~ 2022년 11월 16일(수) diff --git a/src/Editor/Editor.js b/src/Editor/Editor.js index bb77a363..c7c32c21 100644 --- a/src/Editor/Editor.js +++ b/src/Editor/Editor.js @@ -4,6 +4,7 @@ import { request } from '../utils/api.js'; import { putContentMethod, putTitleMethod } from '../utils/optionsMethod.js'; import EditorTitle from './EditorTitle.js'; import EditorContent from './EditorContent.js'; +import { documentsUrl } from '../utils/util.js'; function Editor({ target, initialState }) { const page = createElement('section'); @@ -36,7 +37,7 @@ function Editor({ target, initialState }) { this.setState = async (nextState) => { console.log(nextState); // refactor - const post = await request(`/documents/${nextState.postId}`); + const post = await request(`${documentsUrl}/${nextState.postId}`); isObject(post); postTitle.setState(post); postContent.setState(post); diff --git a/src/Editor/EditorContent.js b/src/Editor/EditorContent.js index 06a87783..8eee61f7 100644 --- a/src/Editor/EditorContent.js +++ b/src/Editor/EditorContent.js @@ -3,6 +3,7 @@ import { isString } from '../utils/errorHandler.js'; function EditorContent({ div, initialState, onChangeContent }) { const editorContent = createElement('div'); + editorContent.className = 'editor-content'; this.state = initialState; this.setState = (nextState) => { diff --git a/src/Editor/EditorTitle.js b/src/Editor/EditorTitle.js index 0a2f05d6..f87a920c 100644 --- a/src/Editor/EditorTitle.js +++ b/src/Editor/EditorTitle.js @@ -3,6 +3,7 @@ import { isString } from '../utils/errorHandler.js'; function EditorTitle({ div, initialState, onChangeTitle }) { const editorTitle = createElement('div'); + editorTitle.className = 'editor-title'; this.state = initialState; div.appendChild(editorTitle); diff --git a/src/Navbar/Navbar.js b/src/Navbar/Navbar.js index 47273f31..ee143f71 100644 --- a/src/Navbar/Navbar.js +++ b/src/Navbar/Navbar.js @@ -52,7 +52,6 @@ function Navbar({ target }) { const que = [currentDocument]; - console.log(que); const queId = [currentDocument.id]; while (que.length > 0) { @@ -63,7 +62,6 @@ function Navbar({ target }) { }); for (let i of queId) { - console.log(i); await deleteMethod(i); } } diff --git a/src/Navbar/NavbarDocumentList.js b/src/Navbar/NavbarDocumentList.js index e475b96a..bb57ddde 100644 --- a/src/Navbar/NavbarDocumentList.js +++ b/src/Navbar/NavbarDocumentList.js @@ -1,6 +1,7 @@ import { createElement, targetClosest, targetContains } from '../utils/dom.js'; import { isNew } from '../utils/errorHandler.js'; import { route } from '../utils/route.js'; +import { documentsUrl } from '../utils/util.js'; function NavbarDocumentList({ target, initialState, onDelete, onAdd }) { isNew(new.target); @@ -61,7 +62,7 @@ function NavbarDocumentList({ target, initialState, onDelete, onAdd }) { onAdd(postId); } else { // refactor 해야함 - route(`/documents/${postId}`); + route(`${documentsUrl}/${postId}`); } }); }; diff --git a/src/style/ui/modules/editor.css b/src/style/ui/modules/editor.css index ccbb82e4..c881cc94 100644 --- a/src/style/ui/modules/editor.css +++ b/src/style/ui/modules/editor.css @@ -53,3 +53,11 @@ button:hover { border-radius: 5px; color: black; } + +.editor-content { + height: 100em; +} + +textarea { + background-color: red; +} diff --git a/src/utils/optionsMethod.js b/src/utils/optionsMethod.js index c3300c86..32627c59 100644 --- a/src/utils/optionsMethod.js +++ b/src/utils/optionsMethod.js @@ -1,48 +1,46 @@ -import {request} from "./api.js"; -import {documentsUrl} from "./util.js"; +import { request } from './api.js'; +import { documentsUrl } from './util.js'; -export const putTitleMethod =(id,title)=>{ - return request(`/documents/${id}`,{ - method:'PUT', - body:JSON.stringify({ - title : title, - }), +export const putTitleMethod = (id, title) => { + return request(`${documentsUrl}/${id}`, { + method: 'PUT', + body: JSON.stringify({ + title: title, + }), }); -} +}; -export const putContentMethod =(id,content)=>{ - return request(`/documents/${id}`,{ - method:'PUT', - body:JSON.stringify({ - content : content, +export const putContentMethod = (id, content) => { + return request(`${documentsUrl}/${id}`, { + method: 'PUT', + body: JSON.stringify({ + content: content, }), }); -} - +}; export const addMethod = (id) => { - return request('/documents', { + return request(`${documentsUrl}`, { method: 'POST', body: JSON.stringify({ title: '', - parent: id - }) + parent: id, + }), }); +}; -} - -export const addHeaderMethod =(documentsUrl)=>{ - return request(`${documentsUrl}`,{ - method : 'POST', +export const addHeaderMethod = (documentsUrl) => { + return request(`${documentsUrl}`, { + method: 'POST', boyd: JSON.stringify({ - title:'', - parent : null, - }) + title: '', + parent: null, + }), }); -} +}; export const deleteMethod = (id) => { - return request(`/documents/${id}`, { - method: 'DELETE' + return request(`${documentsUrl}/${id}`, { + method: 'DELETE', }); -} +}; From db210740d646d67a0e5901a88c9a5c016a0a8406 Mon Sep 17 00:00:00 2001 From: Seung-hwan285 Date: Thu, 17 Nov 2022 04:09:11 +0900 Subject: [PATCH 16/29] =?UTF-8?q?refactor:=20tabWidth=202=EB=A1=9C=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- package.json | 2 +- src/App.js | 1 - src/Editor/Editor.js | 76 ++++++++------- src/Editor/EditorContent.js | 76 ++++++++------- src/Editor/EditorTitle.js | 70 +++++++------- src/Navbar/Navbar.js | 154 +++++++++++++++---------------- src/Navbar/NavbarDocumentList.js | 72 +++++++-------- src/Navbar/NavbarHeader.js | 51 +++++----- src/style/ui/modules/editor.css | 68 +++++++------- src/style/ui/modules/navbar.css | 56 +++++------ src/utils/optionsMethod.js | 58 ++++++------ src/utils/route.js | 7 +- 13 files changed, 339 insertions(+), 354 deletions(-) diff --git a/README.md b/README.md index 1883abf9..30e4153e 100644 --- a/README.md +++ b/README.md @@ -20,10 +20,10 @@ - [x] 상위 Document 삭제하면 최하위 Document 삭제 안되는 현상 - [x] 예외처리 작업, '/documents'-> documentsUrl 변경 - [x] Editor content 부분 textarea 렌더링 했을때 2 개행 이상부터 잘려서 안나오는 현상 +- [x] Editor content 일정 개행 이상 넘어가면 title 안보이는 현상 - [ ] 버튼 이미지 넣어서 관리 -> 현재 text로 들어가 있음 - [ ] 편집기 하단에는 Documents의 하위 Document 링크를 렌더링하도록 생성 - [ ] onDelete 리팩토링 필요 -- [ ] 정상적으로 삭제 기능 동작, Delete 404 에러 나오고있음 -> 물어보기 - 프로젝트 기한 - 프로젝트 수행 기간 : 2022년 11월 8일(화) ~ 2022년 11월 16일(수) diff --git a/package.json b/package.json index 7a7ab43f..7c902b95 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "singleQuote": true, "semi": true, "useTabs": false, - "tabWidth": 4, + "tabWidth": 2, "trailingComma": "all", "printWidth": 100, "bracketSpacing": true, diff --git a/src/App.js b/src/App.js index 25a3f241..91456888 100644 --- a/src/App.js +++ b/src/App.js @@ -8,7 +8,6 @@ function App({ target }) { const postEditPage = new Editor({ target, initialState: { - postId: 'new', title: '', content: '', }, diff --git a/src/Editor/Editor.js b/src/Editor/Editor.js index c7c32c21..84092246 100644 --- a/src/Editor/Editor.js +++ b/src/Editor/Editor.js @@ -7,48 +7,46 @@ import EditorContent from './EditorContent.js'; import { documentsUrl } from '../utils/util.js'; function Editor({ target, initialState }) { - const page = createElement('section'); - page.className = 'content'; - - const editor = createElement('div'); - editor.className = 'editor'; + const page = createElement('section'); + page.className = 'content'; + + const editor = createElement('div'); + editor.className = 'editor'; + + page.appendChild(editor); + target.appendChild(page); + + const postTitle = new EditorTitle({ + div: editor, + initialState: initialState, + + onChangeTitle: async ({ id, title }) => { + setTimeout(await putTitleMethod(id, title), 2000); + }, + }); + + const postContent = new EditorContent({ + div: editor, + initialState: initialState, + + onChangeContent: async ({ id, content }) => { + setTimeout(await putContentMethod(id, content), 2000); + }, + }); + + this.setState = async (nextState) => { + const post = await request(`${documentsUrl}/${nextState.postId}`); + isObject(post); + postTitle.setState(post); + postContent.setState(post); + this.render(); + }; - page.appendChild(editor); + this.render = () => { target.appendChild(page); + }; - const postTitle = new EditorTitle({ - div: editor, - initialState: initialState, - - onChangeTitle: async ({ id, title }) => { - setTimeout(await putTitleMethod(id, title), 2000); - }, - }); - - const postContent = new EditorContent({ - div: editor, - initialState: initialState, - - onChangeContent: async ({ id, content }) => { - setTimeout(await putContentMethod(id, content), 2000); - }, - }); - - this.setState = async (nextState) => { - console.log(nextState); - // refactor - const post = await request(`${documentsUrl}/${nextState.postId}`); - isObject(post); - postTitle.setState(post); - postContent.setState(post); - this.render(); - }; - - this.render = () => { - target.appendChild(page); - }; - - this.render(); + this.render(); } export default Editor; diff --git a/src/Editor/EditorContent.js b/src/Editor/EditorContent.js index 8eee61f7..e07b8404 100644 --- a/src/Editor/EditorContent.js +++ b/src/Editor/EditorContent.js @@ -2,46 +2,44 @@ import { createElement } from '../utils/dom.js'; import { isString } from '../utils/errorHandler.js'; function EditorContent({ div, initialState, onChangeContent }) { - const editorContent = createElement('div'); - editorContent.className = 'editor-content'; - this.state = initialState; - - this.setState = (nextState) => { - this.state = nextState; - const { content } = this.state; - - this.render(); - editorContent.querySelector('.content').value = content && content; - }; - - this.render = () => { - const { content } = this.state; - - // oninput : textarea Enter 누르면 높이 자동 조절 - editorContent.innerHTML = ``; - - div.appendChild(editorContent); - }; - - const onKeyUpContent = () => { - editorContent.addEventListener('keyup', (e) => { - const { name } = e.target; - const contentValue = e.target.value; - isString(contentValue); - const nextState = { - ...this.state, - [name]: contentValue, - }; - - onChangeContent(nextState); - }); - }; - onKeyUpContent(); + const editorContent = createElement('div'); + editorContent.className = 'editor-content'; + this.state = initialState; + + this.setState = (nextState) => { + this.state = nextState; + const { content } = this.state; + this.render(); + editorContent.querySelector('.content').value = content && content; + }; + + this.render = () => { + const { content } = this.state; + + editorContent.innerHTML = ``; + + div.appendChild(editorContent); + }; + + const onKeyUpContent = () => { + editorContent.addEventListener('keyup', (e) => { + const { name } = e.target; + const contentValue = e.target.value; + isString(contentValue); + const nextState = { + ...this.state, + [name]: contentValue, + }; + + onChangeContent(nextState); + }); + }; + onKeyUpContent(); + this.render(); } export default EditorContent; diff --git a/src/Editor/EditorTitle.js b/src/Editor/EditorTitle.js index f87a920c..d5b7891d 100644 --- a/src/Editor/EditorTitle.js +++ b/src/Editor/EditorTitle.js @@ -2,45 +2,43 @@ import { $, createElement } from '../utils/dom.js'; import { isString } from '../utils/errorHandler.js'; function EditorTitle({ div, initialState, onChangeTitle }) { - const editorTitle = createElement('div'); - editorTitle.className = 'editor-title'; - this.state = initialState; + const editorTitle = createElement('div'); + editorTitle.className = 'editor-title'; + this.state = initialState; - div.appendChild(editorTitle); + div.appendChild(editorTitle); - this.setState = (nextState) => { - this.state = nextState; - // null 나오는게 맞음 헤더 버튼 눌렀을 때 - const { title } = this.state; - let el = $('.title'); - // null 나오는게 맞음 헤더 버튼 눌렀을 때 - this.render(); - editorTitle.querySelector('.title').value = title && title; - }; - - this.render = () => { - const { title } = this.state; - editorTitle.innerHTML = ``; - div.appendChild(editorTitle); - }; - - const onKeyupEditorTitle = () => { - editorTitle.addEventListener('keyup', (e) => { - const { name } = e.target; - const titleValue = e.target.value; - - isString(titleValue); - - const nextState = { - ...this.state, - [name]: titleValue, - }; - - onChangeTitle(nextState); - }); - }; + this.setState = (nextState) => { + this.state = nextState; + const { title } = this.state; + let el = $('.title'); this.render(); - onKeyupEditorTitle(); + editorTitle.querySelector('.title').value = title && title; + }; + + this.render = () => { + const { title } = this.state; + editorTitle.innerHTML = ``; + div.appendChild(editorTitle); + }; + + const onKeyupEditorTitle = () => { + editorTitle.addEventListener('keyup', (e) => { + const { name } = e.target; + const titleValue = e.target.value; + + isString(titleValue); + + const nextState = { + ...this.state, + [name]: titleValue, + }; + + onChangeTitle(nextState); + }); + }; + this.render(); + onKeyupEditorTitle(); } export default EditorTitle; diff --git a/src/Navbar/Navbar.js b/src/Navbar/Navbar.js index ee143f71..d4bf30b1 100644 --- a/src/Navbar/Navbar.js +++ b/src/Navbar/Navbar.js @@ -9,83 +9,83 @@ import NavbarDocumentList from './NavbarDocumentList.js'; import NavbarHeader from './NavbarHeader.js'; function Navbar({ target }) { - isNew(new.target); - const nav = createElement('nav'); - nav.className = 'sidebar'; - - new NavbarHeader({ - target: nav, - initialState: { - text: 'Notion', - button: { - text: '+', - }, - }, - }); - - const documentList = new NavbarDocumentList({ - target: nav, - initialState: [], - onDelete: async (id) => { - // 현재 Document 삭제하게 되면 하위 Documents 전부 삭제 - const findCurrentId = () => { - const rootDocument = [...documentList.state]; - - while (rootDocument.length > 0) { - const cur = rootDocument.shift(); - - if (parseInt(cur.id) === parseInt(id)) { - console.log(cur); - return cur; - } - - cur.documents.forEach((el) => { - rootDocument.push(el); - }); - } - }; - - // 현재 하위 document 가 3개 이상이면 하위 document 값이 삭제가 안되고 있음 - // 하위 document 2개씩만 삭제되는 현상 - const handlerDelete = async () => { - const currentDocument = findCurrentId(); - - const que = [currentDocument]; - - const queId = [currentDocument.id]; - - while (que.length > 0) { - const current = que.shift(); - current.documents.forEach((el) => { - que.push(el); - queId.push(el.id); - }); - - for (let i of queId) { - await deleteMethod(i); - } - } - }; - - await handlerDelete(); - route('/'); - }, - - onAdd: async (id) => { - const newPost = await addMethod(id); - route(`${documentsUrl}/${newPost.id}`); - }, - }); - - this.setState = async () => { - const posts = await request(`${documentsUrl}`); - documentList.setState(posts); - this.render(); - }; - - this.render = async () => { - target.appendChild(nav); - }; + isNew(new.target); + const nav = createElement('nav'); + nav.className = 'sidebar'; + + new NavbarHeader({ + target: nav, + initialState: { + text: 'Notion', + button: { + text: '+', + }, + }, + }); + + const documentList = new NavbarDocumentList({ + target: nav, + initialState: [], + onDelete: async (id) => { + // 현재 Document 삭제하게 되면 하위 Documents 전부 삭제 + const findCurrentId = () => { + const rootDocument = [...documentList.state]; + + while (rootDocument.length > 0) { + const cur = rootDocument.shift(); + + if (parseInt(cur.id) === parseInt(id)) { + console.log(cur); + return cur; + } + + cur.documents.forEach((el) => { + rootDocument.push(el); + }); + } + }; + + // 현재 하위 document 가 3개 이상이면 하위 document 값이 삭제가 안되고 있음 + // 하위 document 2개씩만 삭제되는 현상 + const handlerDelete = async () => { + const currentDocument = findCurrentId(); + + const que = [currentDocument]; + + const queId = [currentDocument.id]; + + while (que.length > 0) { + const current = que.shift(); + current.documents.forEach((el) => { + que.push(el); + queId.push(el.id); + }); + + for (let i of queId) { + await deleteMethod(i); + } + } + }; + + await handlerDelete(); + route('/'); + }, + + onAdd: async (id) => { + const newPost = await addMethod(id); + route(`${documentsUrl}/${newPost.id}`); + }, + }); + + this.setState = async () => { + const posts = await request(`${documentsUrl}`); + documentList.setState(posts); + this.render(); + }; + + this.render = async () => { + target.appendChild(nav); + }; } export default Navbar; diff --git a/src/Navbar/NavbarDocumentList.js b/src/Navbar/NavbarDocumentList.js index bb57ddde..9dd5fa6f 100644 --- a/src/Navbar/NavbarDocumentList.js +++ b/src/Navbar/NavbarDocumentList.js @@ -4,30 +4,30 @@ import { route } from '../utils/route.js'; import { documentsUrl } from '../utils/util.js'; function NavbarDocumentList({ target, initialState, onDelete, onAdd }) { - isNew(new.target); - const postList = createElement('div'); + isNew(new.target); + const postList = createElement('div'); - target.appendChild(postList); + target.appendChild(postList); - this.state = initialState; + this.state = initialState; - this.setState = (nextState) => { - this.state = nextState; - this.render(); - }; + this.setState = (nextState) => { + this.state = nextState; + this.render(); + }; - this.render = () => { - postList.innerHTML = paintDocument(this.state); - onClickDocument(); - }; + this.render = () => { + postList.innerHTML = paintDocument(this.state); + onClickDocument(); + }; - const paintDocument = (docuements) => { - return ` -
    - + const paintDocument = (docuements) => { + return ` +
      + ${docuements - .map( - (post) => ` + .map( + (post) => `
    • @@ -44,29 +44,29 @@ function NavbarDocumentList({ target, initialState, onDelete, onAdd }) { ${post.documents.length ? paintDocument(post.documents) : ''}
    • `, - ) - .join('')} + ) + .join('')}
    `; - }; + }; - const onClickDocument = () => { - const ul = postList.querySelector('.document-list'); + const onClickDocument = () => { + const ul = postList.querySelector('.document-list'); - ul.addEventListener('click', (e) => { - const postId = targetClosest(e, 'li').id; + ul.addEventListener('click', (e) => { + const postId = targetClosest(e, 'li').id; - if (targetContains(e, 'delete-btn')) { - onDelete(postId); - } else if (targetContains(e, 'add-btn')) { - onAdd(postId); - } else { - // refactor 해야함 - route(`${documentsUrl}/${postId}`); - } - }); - }; - this.render(); + if (targetContains(e, 'delete-btn')) { + onDelete(postId); + } else if (targetContains(e, 'add-btn')) { + onAdd(postId); + } else { + // refactor 해야함 + route(`${documentsUrl}/${postId}`); + } + }); + }; + this.render(); } export default NavbarDocumentList; diff --git a/src/Navbar/NavbarHeader.js b/src/Navbar/NavbarHeader.js index 92c78b0f..93cd9371 100644 --- a/src/Navbar/NavbarHeader.js +++ b/src/Navbar/NavbarHeader.js @@ -5,36 +5,35 @@ import { documentsUrl } from '../utils/util.js'; import { addHeaderMethod } from '../utils/optionsMethod.js'; function NavbarHeader({ target, initialState }) { - isNew(new.target); + isNew(new.target); - const header = createElement('div'); - header.className = 'header'; - this.state = initialState; + const header = createElement('div'); + header.className = 'header'; + this.state = initialState; - this.render = () => { - header.innerHTML = ` - ${this.state.text} - - - `; - target.appendChild(header); - }; + this.render = () => { + header.innerHTML = ` + ${this.state.text} + + + `; + target.appendChild(header); + }; - // 해당 제목클릭 했을때 page 이동 - const onClickHeader = () => { - header.addEventListener('click', async (e) => { - const homeBtn = targetClosest(e, '.home-btn'); - if (homeBtn) { - route('/'); - } else { - const createPost = await addHeaderMethod(documentsUrl); - route(`${documentsUrl}/${createPost.id}`); - } - }); - }; - this.render(); + const onClickHeader = () => { + header.addEventListener('click', async (e) => { + const homeBtn = targetClosest(e, '.home-btn'); + if (homeBtn) { + route('/'); + } else { + const createPost = await addHeaderMethod(documentsUrl); + route(`${documentsUrl}/${createPost.id}`); + } + }); + }; + this.render(); - onClickHeader(); + onClickHeader(); } export default NavbarHeader; diff --git a/src/style/ui/modules/editor.css b/src/style/ui/modules/editor.css index c881cc94..54cd9bba 100644 --- a/src/style/ui/modules/editor.css +++ b/src/style/ui/modules/editor.css @@ -1,63 +1,57 @@ .app { - display: flex; - height: 100vh; + display: flex; + height: 100vh; } .content { - width: 100%; - height: 70%; - border: none; - outline: none; - /*overflow-y: scroll;*/ - font-size: 20px; - display: flex; - justify-content: space-around; - margin-top: 5%; - /*-ms-overflow-style: none;*/ + width: 100%; + height: 70%; + border: none; + outline: none; + overflow: auto; + font-size: 20px; + display: flex; + justify-content: space-around; + margin-top: 5%; + /*-ms-overflow-style: none;*/ } .content ::-webkit-scrollbar { - display: none; - height: 100em; + display: none; + height: 100em; } .editor { - width: 60%; - overflow-y: hidden; + width: 60%; } .title { - width: 100%; - display: block; - border: none; - outline: none; - font-size: 38px; + width: 100%; + display: block; + border: none; + outline: none; + font-size: 38px; } .add { - width: 25px; + width: 25px; } button { - border: none; - outline: none; - padding: 0; - overflow: hidden; - background: none; - margin-left: 30px; - cursor: pointer; + border: none; + outline: none; + padding: 0; + background: none; + margin-left: 30px; + cursor: pointer; } button:hover { - border: solid 1px #aca99e; - border-radius: 5px; - color: black; + border: solid 1px #aca99e; + border-radius: 5px; + color: black; } .editor-content { - height: 100em; -} - -textarea { - background-color: red; + height: 100vh; } diff --git a/src/style/ui/modules/navbar.css b/src/style/ui/modules/navbar.css index d04d19f2..f146fa7e 100644 --- a/src/style/ui/modules/navbar.css +++ b/src/style/ui/modules/navbar.css @@ -1,57 +1,57 @@ .header { - margin-bottom: 30px; + margin-bottom: 30px; } .document-list { - padding-left: 10px; + padding-left: 10px; } .list-style-type { - list-style-type: none; + list-style-type: none; } .sidebar { - width: 20%; - font-size: 15px; - line-height: 1rem; - background-color: rgb(245, 244, 241); - padding: 1em; + width: 20%; + font-size: 15px; + line-height: 1rem; + background-color: rgb(245, 244, 241); + padding: 1em; } .row-item { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 5px; - min-height: 27px; - color: #cccbc7; - cursor: pointer; - padding-left: 10px; + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 5px; + min-height: 27px; + color: #cccbc7; + cursor: pointer; + padding-left: 10px; } .row-item:hover { - background: rgba(55, 53, 47, 0.08); - color: black; + background: rgba(55, 53, 47, 0.08); + color: black; } .item-text { - display: flex; - width: 75%; - align-items: center; + display: flex; + width: 75%; + align-items: center; } .item-button { - display: flex; - flex-direction: row-reverse; - /*align-items: center;*/ - width: inherit; - /*padding-left: 20px;*/ + display: flex; + flex-direction: row-reverse; + /*align-items: center;*/ + width: inherit; + /*padding-left: 20px;*/ } .delete-btn { - font-size: 18px; + font-size: 18px; } .add-btn { - font-size: 18px; + font-size: 18px; } diff --git a/src/utils/optionsMethod.js b/src/utils/optionsMethod.js index 32627c59..adc59edb 100644 --- a/src/utils/optionsMethod.js +++ b/src/utils/optionsMethod.js @@ -2,45 +2,45 @@ import { request } from './api.js'; import { documentsUrl } from './util.js'; export const putTitleMethod = (id, title) => { - return request(`${documentsUrl}/${id}`, { - method: 'PUT', - body: JSON.stringify({ - title: title, - }), - }); + return request(`${documentsUrl}/${id}`, { + method: 'PUT', + body: JSON.stringify({ + title: title, + }), + }); }; export const putContentMethod = (id, content) => { - return request(`${documentsUrl}/${id}`, { - method: 'PUT', - body: JSON.stringify({ - content: content, - }), - }); + return request(`${documentsUrl}/${id}`, { + method: 'PUT', + body: JSON.stringify({ + content: content, + }), + }); }; export const addMethod = (id) => { - return request(`${documentsUrl}`, { - method: 'POST', - body: JSON.stringify({ - title: '', - parent: id, - }), - }); + return request(`${documentsUrl}`, { + method: 'POST', + body: JSON.stringify({ + title: '', + parent: id, + }), + }); }; export const addHeaderMethod = (documentsUrl) => { - return request(`${documentsUrl}`, { - method: 'POST', - boyd: JSON.stringify({ - title: '', - parent: null, - }), - }); + return request(`${documentsUrl}`, { + method: 'POST', + boyd: JSON.stringify({ + title: '', + parent: null, + }), + }); }; export const deleteMethod = (id) => { - return request(`${documentsUrl}/${id}`, { - method: 'DELETE', - }); + return request(`${documentsUrl}/${id}`, { + method: 'DELETE', + }); }; diff --git a/src/utils/route.js b/src/utils/route.js index a32aeae7..2a92ccb7 100644 --- a/src/utils/route.js +++ b/src/utils/route.js @@ -1,7 +1,7 @@ import { ROUTE_CHANGE_NAME } from './util.js'; -export const initRouter = onRoute => { - window.addEventListener(ROUTE_CHANGE_NAME, e => { +export const initRouter = (onRoute) => { + window.addEventListener(ROUTE_CHANGE_NAME, (e) => { const { nextUrl } = e.detail; if (nextUrl) { @@ -11,7 +11,7 @@ export const initRouter = onRoute => { }); }; -export const route = nextUrl => { +export const route = (nextUrl) => { if (nextUrl) { window.dispatchEvent( new CustomEvent(ROUTE_CHANGE_NAME, { @@ -22,4 +22,3 @@ export const route = nextUrl => { ); } }; - From abd5f453636ae866e4f6bbe4b39be9ae4f2d89b0 Mon Sep 17 00:00:00 2001 From: Seung-hwan285 Date: Thu, 17 Nov 2022 04:20:54 +0900 Subject: [PATCH 17/29] =?UTF-8?q?feat=20:=20=EA=B0=9C=ED=96=89=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/main.js b/main.js index 121d316f..6dd485e7 100644 --- a/main.js +++ b/main.js @@ -1,6 +1,5 @@ -import App from "./src/App.js"; +import App from './src/App.js'; const app = document.querySelector('.app'); - -new App({target :app}); \ No newline at end of file +new App({ target: app }); From 010431c15fd778b944b2b54df39dedc5769e1890 Mon Sep 17 00:00:00 2001 From: Seung-hwan285 Date: Thu, 17 Nov 2022 16:34:19 +0900 Subject: [PATCH 18/29] =?UTF-8?q?style=20:=20documentList=20=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=20=EB=94=94=EC=9E=90=EC=9D=B8=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- src/Editor/Editor.js | 3 ++- src/Editor/EditorContent.js | 3 ++- src/Editor/EditorTitle.js | 3 ++- src/Navbar/NavbarDocumentList.js | 8 ++++---- src/style/ui/modules/editor.css | 15 --------------- src/style/ui/modules/navbar.css | 15 +++++++++++++++ 7 files changed, 26 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 30e4153e..e60da14b 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ - [x] 예외처리 작업, '/documents'-> documentsUrl 변경 - [x] Editor content 부분 textarea 렌더링 했을때 2 개행 이상부터 잘려서 안나오는 현상 - [x] Editor content 일정 개행 이상 넘어가면 title 안보이는 현상 -- [ ] 버튼 이미지 넣어서 관리 -> 현재 text로 들어가 있음 +- [x] 버튼 이미지 넣어서 관리 -> 현재 text로 들어가 있음 - [ ] 편집기 하단에는 Documents의 하위 Document 링크를 렌더링하도록 생성 - [ ] onDelete 리팩토링 필요 diff --git a/src/Editor/Editor.js b/src/Editor/Editor.js index 84092246..c1c234af 100644 --- a/src/Editor/Editor.js +++ b/src/Editor/Editor.js @@ -1,5 +1,5 @@ import { createElement } from '../utils/dom.js'; -import { isObject } from '../utils/errorHandler.js'; +import { isNew, isObject } from '../utils/errorHandler.js'; import { request } from '../utils/api.js'; import { putContentMethod, putTitleMethod } from '../utils/optionsMethod.js'; import EditorTitle from './EditorTitle.js'; @@ -7,6 +7,7 @@ import EditorContent from './EditorContent.js'; import { documentsUrl } from '../utils/util.js'; function Editor({ target, initialState }) { + isNew(new.target); const page = createElement('section'); page.className = 'content'; diff --git a/src/Editor/EditorContent.js b/src/Editor/EditorContent.js index e07b8404..ec2e45e6 100644 --- a/src/Editor/EditorContent.js +++ b/src/Editor/EditorContent.js @@ -1,7 +1,8 @@ import { createElement } from '../utils/dom.js'; -import { isString } from '../utils/errorHandler.js'; +import { isNew, isString } from '../utils/errorHandler.js'; function EditorContent({ div, initialState, onChangeContent }) { + isNew(new.target); const editorContent = createElement('div'); editorContent.className = 'editor-content'; this.state = initialState; diff --git a/src/Editor/EditorTitle.js b/src/Editor/EditorTitle.js index d5b7891d..d2f52581 100644 --- a/src/Editor/EditorTitle.js +++ b/src/Editor/EditorTitle.js @@ -1,7 +1,8 @@ import { $, createElement } from '../utils/dom.js'; -import { isString } from '../utils/errorHandler.js'; +import { isNew, isString } from '../utils/errorHandler.js'; function EditorTitle({ div, initialState, onChangeTitle }) { + isNew(new.target); const editorTitle = createElement('div'); editorTitle.className = 'editor-title'; this.state = initialState; diff --git a/src/Navbar/NavbarDocumentList.js b/src/Navbar/NavbarDocumentList.js index 9dd5fa6f..c620dbab 100644 --- a/src/Navbar/NavbarDocumentList.js +++ b/src/Navbar/NavbarDocumentList.js @@ -37,8 +37,8 @@ function NavbarDocumentList({ target, initialState, onDelete, onAdd }) {
    - - + +
    ${post.documents.length ? paintDocument(post.documents) : ''} @@ -56,9 +56,9 @@ function NavbarDocumentList({ target, initialState, onDelete, onAdd }) { ul.addEventListener('click', (e) => { const postId = targetClosest(e, 'li').id; - if (targetContains(e, 'delete-btn')) { + if (targetContains(e, 'fa-minus-square')) { onDelete(postId); - } else if (targetContains(e, 'add-btn')) { + } else if (targetContains(e, 'fa-plus-square')) { onAdd(postId); } else { // refactor 해야함 diff --git a/src/style/ui/modules/editor.css b/src/style/ui/modules/editor.css index 54cd9bba..86e2a78e 100644 --- a/src/style/ui/modules/editor.css +++ b/src/style/ui/modules/editor.css @@ -37,21 +37,6 @@ width: 25px; } -button { - border: none; - outline: none; - padding: 0; - background: none; - margin-left: 30px; - cursor: pointer; -} - -button:hover { - border: solid 1px #aca99e; - border-radius: 5px; - color: black; -} - .editor-content { height: 100vh; } diff --git a/src/style/ui/modules/navbar.css b/src/style/ui/modules/navbar.css index f146fa7e..f0cf0a20 100644 --- a/src/style/ui/modules/navbar.css +++ b/src/style/ui/modules/navbar.css @@ -48,6 +48,21 @@ /*padding-left: 20px;*/ } +button { + border: none; + outline: none; + padding: 0; + background: none; + margin-left: 30px; + cursor: pointer; +} + +button:hover { + border: solid 1px #aca99e; + border-radius: 5px; + color: black; +} + .delete-btn { font-size: 18px; } From 7b74168e7cce3297328e6e18a00b26c1d84e5459 Mon Sep 17 00:00:00 2001 From: Seung-hwan285 Date: Thu, 17 Nov 2022 18:03:50 +0900 Subject: [PATCH 19/29] =?UTF-8?q?style=20:=20header=20button=20style=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Editor/EditorContent.js | 3 ++- src/Editor/EditorTitle.js | 3 +-- src/Navbar/NavbarDocumentList.js | 10 +++++++--- src/Navbar/NavbarHeader.js | 2 +- src/style/ui/modules/navbar.css | 10 ++++++++++ 5 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/Editor/EditorContent.js b/src/Editor/EditorContent.js index ec2e45e6..850a3602 100644 --- a/src/Editor/EditorContent.js +++ b/src/Editor/EditorContent.js @@ -39,8 +39,9 @@ function EditorContent({ div, initialState, onChangeContent }) { onChangeContent(nextState); }); }; - onKeyUpContent(); + this.render(); + onKeyUpContent(); } export default EditorContent; diff --git a/src/Editor/EditorTitle.js b/src/Editor/EditorTitle.js index d2f52581..9e6b52d5 100644 --- a/src/Editor/EditorTitle.js +++ b/src/Editor/EditorTitle.js @@ -1,4 +1,4 @@ -import { $, createElement } from '../utils/dom.js'; +import { createElement } from '../utils/dom.js'; import { isNew, isString } from '../utils/errorHandler.js'; function EditorTitle({ div, initialState, onChangeTitle }) { @@ -12,7 +12,6 @@ function EditorTitle({ div, initialState, onChangeTitle }) { this.setState = (nextState) => { this.state = nextState; const { title } = this.state; - let el = $('.title'); this.render(); editorTitle.querySelector('.title').value = title && title; }; diff --git a/src/Navbar/NavbarDocumentList.js b/src/Navbar/NavbarDocumentList.js index c620dbab..f2980ccc 100644 --- a/src/Navbar/NavbarDocumentList.js +++ b/src/Navbar/NavbarDocumentList.js @@ -28,19 +28,22 @@ function NavbarDocumentList({ target, initialState, onDelete, onAdd }) { ${docuements .map( (post) => ` + +
  • - +
    - +
    ${post.title ? post.title : '제목 없음'}
    - +
    + ${post.documents.length ? paintDocument(post.documents) : ''}
  • `, @@ -55,6 +58,7 @@ function NavbarDocumentList({ target, initialState, onDelete, onAdd }) { ul.addEventListener('click', (e) => { const postId = targetClosest(e, 'li').id; + console.log(); if (targetContains(e, 'fa-minus-square')) { onDelete(postId); diff --git a/src/Navbar/NavbarHeader.js b/src/Navbar/NavbarHeader.js index 93cd9371..d833a085 100644 --- a/src/Navbar/NavbarHeader.js +++ b/src/Navbar/NavbarHeader.js @@ -14,7 +14,7 @@ function NavbarHeader({ target, initialState }) { this.render = () => { header.innerHTML = ` ${this.state.text} - + `; target.appendChild(header); diff --git a/src/style/ui/modules/navbar.css b/src/style/ui/modules/navbar.css index f0cf0a20..86eb5868 100644 --- a/src/style/ui/modules/navbar.css +++ b/src/style/ui/modules/navbar.css @@ -38,6 +38,7 @@ display: flex; width: 75%; align-items: center; + margin-left: 10px; } .item-button { @@ -70,3 +71,12 @@ button:hover { .add-btn { font-size: 18px; } + +.home-btn { + position: absolute; + left: 13%; +} +.home-plus-btn { + position: absolute; + left: 3rem; +} From 27638ce3f29dea5adbddec95cc0ff9b0df7214bd Mon Sep 17 00:00:00 2001 From: Seung-hwan285 Date: Sat, 19 Nov 2022 17:40:57 +0900 Subject: [PATCH 20/29] =?UTF-8?q?fix=20:=20404=20=EC=97=90=EB=9F=AC=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- src/Editor/Editor.js | 87 ++++++++++-------- src/Editor/EditorContent.js | 64 ++++++------- src/Editor/EditorSubContetn.js | 26 ++++++ src/Editor/EditorTitle.js | 68 +++++++------- src/Navbar/Navbar.js | 151 +++++++++++++++---------------- src/Navbar/NavbarDocumentList.js | 75 ++++++++------- src/Navbar/NavbarHeader.js | 50 +++++----- src/style/ui/modules/editor.css | 47 +++++----- src/utils/optionsMethod.js | 58 ++++++------ 10 files changed, 329 insertions(+), 299 deletions(-) create mode 100644 src/Editor/EditorSubContetn.js diff --git a/package.json b/package.json index 7c902b95..7a7ab43f 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "singleQuote": true, "semi": true, "useTabs": false, - "tabWidth": 2, + "tabWidth": 4, "trailingComma": "all", "printWidth": 100, "bracketSpacing": true, diff --git a/src/Editor/Editor.js b/src/Editor/Editor.js index c1c234af..d99374ee 100644 --- a/src/Editor/Editor.js +++ b/src/Editor/Editor.js @@ -5,49 +5,56 @@ import { putContentMethod, putTitleMethod } from '../utils/optionsMethod.js'; import EditorTitle from './EditorTitle.js'; import EditorContent from './EditorContent.js'; import { documentsUrl } from '../utils/util.js'; +import EditorSubContetn from './EditorSubContetn.js'; function Editor({ target, initialState }) { - isNew(new.target); - const page = createElement('section'); - page.className = 'content'; - - const editor = createElement('div'); - editor.className = 'editor'; - - page.appendChild(editor); - target.appendChild(page); - - const postTitle = new EditorTitle({ - div: editor, - initialState: initialState, - - onChangeTitle: async ({ id, title }) => { - setTimeout(await putTitleMethod(id, title), 2000); - }, - }); - - const postContent = new EditorContent({ - div: editor, - initialState: initialState, - - onChangeContent: async ({ id, content }) => { - setTimeout(await putContentMethod(id, content), 2000); - }, - }); - - this.setState = async (nextState) => { - const post = await request(`${documentsUrl}/${nextState.postId}`); - isObject(post); - postTitle.setState(post); - postContent.setState(post); - this.render(); - }; - - this.render = () => { - target.appendChild(page); - }; + isNew(new.target); + const page = createElement('section'); + page.className = 'content'; + + const editor = createElement('div'); + editor.className = 'editor'; + + this.state = initialState; + const postTitle = new EditorTitle({ + div: editor, + initialState: initialState, + + onChangeTitle: async ({ id, title }) => { + setTimeout(await putTitleMethod(id, title), 2000); + }, + }); + + const postContent = new EditorContent({ + div: editor, + initialState: initialState, + + onChangeContent: async ({ id, content }) => { + setTimeout(await putContentMethod(id, content), 2000); + }, + }); + + const postSub = new EditorSubContetn({ + div: editor, + initialState: initialState, + }); + + this.setState = async (nextState) => { + const post = await request(`${documentsUrl}/${nextState.postId}`); + isObject(post); + postTitle.setState(post); + postContent.setState(post); + postSub.setState(post); + this.render(); + }; + + this.render = () => { + // editor2.innerHTML = createSubDoucuments(); + page.appendChild(editor); + target.appendChild(page); + }; - this.render(); + this.render(); } export default Editor; diff --git a/src/Editor/EditorContent.js b/src/Editor/EditorContent.js index 850a3602..a7321b65 100644 --- a/src/Editor/EditorContent.js +++ b/src/Editor/EditorContent.js @@ -2,46 +2,46 @@ import { createElement } from '../utils/dom.js'; import { isNew, isString } from '../utils/errorHandler.js'; function EditorContent({ div, initialState, onChangeContent }) { - isNew(new.target); - const editorContent = createElement('div'); - editorContent.className = 'editor-content'; - this.state = initialState; + isNew(new.target); + const editorContent = createElement('div'); + editorContent.className = 'editor-content'; - this.setState = (nextState) => { - this.state = nextState; - const { content } = this.state; + this.state = initialState; - this.render(); - editorContent.querySelector('.content').value = content && content; - }; + this.setState = (nextState) => { + this.state = nextState; + const { content } = this.state; - this.render = () => { - const { content } = this.state; + this.render(); + editorContent.querySelector('.content').value = content && content; + }; - editorContent.innerHTML = ``; - div.appendChild(editorContent); - }; - - const onKeyUpContent = () => { - editorContent.addEventListener('keyup', (e) => { - const { name } = e.target; - const contentValue = e.target.value; - isString(contentValue); - const nextState = { - ...this.state, - [name]: contentValue, - }; - - onChangeContent(nextState); - }); - }; - - this.render(); - onKeyUpContent(); + div.appendChild(editorContent); + }; + + const onKeyUpContent = () => { + editorContent.addEventListener('keyup', (e) => { + const { name } = e.target; + const contentValue = e.target.value; + isString(contentValue); + const nextState = { + ...this.state, + [name]: contentValue, + }; + + onChangeContent(nextState); + }); + }; + + this.render(); + onKeyUpContent(); } export default EditorContent; diff --git a/src/Editor/EditorSubContetn.js b/src/Editor/EditorSubContetn.js new file mode 100644 index 00000000..d26007c7 --- /dev/null +++ b/src/Editor/EditorSubContetn.js @@ -0,0 +1,26 @@ +import { createElement } from '../utils/dom.js'; + +function EditorSubContetn({ div, initialState }) { + const editorDocuments = createElement('div'); + editorDocuments.className = 'editor-documents'; + + this.state = initialState; + + this.setState = (nextState) => { + this.state = nextState; + this.render(); + }; + + const createSubDocuments = (documents) => { + console.log(documents); + }; + + this.render = () => { + // editorDocuments.innerHTML = createSubDocuments(this.state); + // div.appendChild(editorDocuments); + }; + + this.render(); +} + +export default EditorSubContetn; diff --git a/src/Editor/EditorTitle.js b/src/Editor/EditorTitle.js index 9e6b52d5..53069d98 100644 --- a/src/Editor/EditorTitle.js +++ b/src/Editor/EditorTitle.js @@ -2,43 +2,43 @@ import { createElement } from '../utils/dom.js'; import { isNew, isString } from '../utils/errorHandler.js'; function EditorTitle({ div, initialState, onChangeTitle }) { - isNew(new.target); - const editorTitle = createElement('div'); - editorTitle.className = 'editor-title'; - this.state = initialState; + isNew(new.target); + const editorTitle = createElement('div'); + editorTitle.className = 'editor-title'; + this.state = initialState; - div.appendChild(editorTitle); - - this.setState = (nextState) => { - this.state = nextState; - const { title } = this.state; - this.render(); - editorTitle.querySelector('.title').value = title && title; - }; - - this.render = () => { - const { title } = this.state; - editorTitle.innerHTML = ``; div.appendChild(editorTitle); - }; - - const onKeyupEditorTitle = () => { - editorTitle.addEventListener('keyup', (e) => { - const { name } = e.target; - const titleValue = e.target.value; - isString(titleValue); - - const nextState = { - ...this.state, - [name]: titleValue, - }; - - onChangeTitle(nextState); - }); - }; - this.render(); - onKeyupEditorTitle(); + this.setState = (nextState) => { + this.state = nextState; + const { title } = this.state; + this.render(); + editorTitle.querySelector('.title').value = title && title; + }; + + this.render = () => { + const { title } = this.state; + editorTitle.innerHTML = ``; + div.appendChild(editorTitle); + }; + + const onKeyupEditorTitle = () => { + editorTitle.addEventListener('keyup', (e) => { + const { name } = e.target; + const titleValue = e.target.value; + + isString(titleValue); + + const nextState = { + ...this.state, + [name]: titleValue, + }; + + onChangeTitle(nextState); + }); + }; + this.render(); + onKeyupEditorTitle(); } export default EditorTitle; diff --git a/src/Navbar/Navbar.js b/src/Navbar/Navbar.js index d4bf30b1..2339c339 100644 --- a/src/Navbar/Navbar.js +++ b/src/Navbar/Navbar.js @@ -9,83 +9,80 @@ import NavbarDocumentList from './NavbarDocumentList.js'; import NavbarHeader from './NavbarHeader.js'; function Navbar({ target }) { - isNew(new.target); - const nav = createElement('nav'); - nav.className = 'sidebar'; - - new NavbarHeader({ - target: nav, - initialState: { - text: 'Notion', - button: { - text: '+', - }, - }, - }); - - const documentList = new NavbarDocumentList({ - target: nav, - initialState: [], - onDelete: async (id) => { - // 현재 Document 삭제하게 되면 하위 Documents 전부 삭제 - const findCurrentId = () => { - const rootDocument = [...documentList.state]; - - while (rootDocument.length > 0) { - const cur = rootDocument.shift(); - - if (parseInt(cur.id) === parseInt(id)) { - console.log(cur); - return cur; - } - - cur.documents.forEach((el) => { - rootDocument.push(el); - }); - } - }; - - // 현재 하위 document 가 3개 이상이면 하위 document 값이 삭제가 안되고 있음 - // 하위 document 2개씩만 삭제되는 현상 - const handlerDelete = async () => { - const currentDocument = findCurrentId(); - - const que = [currentDocument]; - - const queId = [currentDocument.id]; - - while (que.length > 0) { - const current = que.shift(); - current.documents.forEach((el) => { - que.push(el); - queId.push(el.id); - }); - - for (let i of queId) { - await deleteMethod(i); - } - } - }; - - await handlerDelete(); - route('/'); - }, - - onAdd: async (id) => { - const newPost = await addMethod(id); - route(`${documentsUrl}/${newPost.id}`); - }, - }); - - this.setState = async () => { - const posts = await request(`${documentsUrl}`); - documentList.setState(posts); - this.render(); - }; - - this.render = async () => { - target.appendChild(nav); - }; + isNew(new.target); + const nav = createElement('nav'); + nav.className = 'sidebar'; + + new NavbarHeader({ + target: nav, + initialState: { + text: 'Notion', + }, + }); + + const documentList = new NavbarDocumentList({ + target: nav, + initialState: [], + onDelete: async (id) => { + const findCurrentId = () => { + const rootDocument = [...documentList.state]; + + while (rootDocument.length > 0) { + const cur = rootDocument.shift(); + + if (parseInt(cur.id) === parseInt(id)) { + console.log(cur); + return cur; + } + + cur.documents.forEach((el) => { + rootDocument.push(el); + }); + } + }; + // 현재 하위 document 가 3개 이상이면 하위 document 값이 삭제가 안되고 있음 + // 하위 document 2개씩만 삭제되는 현상 + + const handlerDelete = async () => { + const currentDocument = findCurrentId(); + + let que = [currentDocument]; + + const queId = [currentDocument.id]; + + while (que.length > 0) { + const current = que.shift(); + current.documents.forEach((el) => { + que.push(el); + queId.push(el.id); + }); + + for (let i of queId) { + await deleteMethod(i); + que = []; + } + } + }; + + await handlerDelete(); + route('/'); + }, + + onAdd: async (id) => { + const newPost = await addMethod(id); + route(`${documentsUrl}/${newPost.id}`); + }, + }); + + this.setState = async () => { + const posts = await request(`${documentsUrl}`); + documentList.setState(posts); + this.render(); + }; + + this.render = async () => { + target.appendChild(nav); + }; } export default Navbar; diff --git a/src/Navbar/NavbarDocumentList.js b/src/Navbar/NavbarDocumentList.js index f2980ccc..89e2abb2 100644 --- a/src/Navbar/NavbarDocumentList.js +++ b/src/Navbar/NavbarDocumentList.js @@ -4,32 +4,30 @@ import { route } from '../utils/route.js'; import { documentsUrl } from '../utils/util.js'; function NavbarDocumentList({ target, initialState, onDelete, onAdd }) { - isNew(new.target); - const postList = createElement('div'); + isNew(new.target); + const postList = createElement('div'); - target.appendChild(postList); + target.appendChild(postList); - this.state = initialState; + this.state = initialState; - this.setState = (nextState) => { - this.state = nextState; - this.render(); - }; + this.setState = (nextState) => { + this.state = nextState; + this.render(); + }; - this.render = () => { - postList.innerHTML = paintDocument(this.state); - onClickDocument(); - }; + this.render = () => { + postList.innerHTML = paintDocument(this.state); + onClickDocument(); + }; - const paintDocument = (docuements) => { - return ` -
      - + const paintDocument = (docuements) => { + return ` +
        + ${docuements - .map( - (post) => ` - - + .map( + (post) => `
      • @@ -47,30 +45,29 @@ function NavbarDocumentList({ target, initialState, onDelete, onAdd }) { ${post.documents.length ? paintDocument(post.documents) : ''}
      • `, - ) - .join('')} + ) + .join('')}
      `; - }; + }; - const onClickDocument = () => { - const ul = postList.querySelector('.document-list'); + const onClickDocument = () => { + const ul = postList.querySelector('.document-list'); - ul.addEventListener('click', (e) => { - const postId = targetClosest(e, 'li').id; - console.log(); + ul.addEventListener('click', (e) => { + const postId = targetClosest(e, 'li').id; - if (targetContains(e, 'fa-minus-square')) { - onDelete(postId); - } else if (targetContains(e, 'fa-plus-square')) { - onAdd(postId); - } else { - // refactor 해야함 - route(`${documentsUrl}/${postId}`); - } - }); - }; - this.render(); + if (targetContains(e, 'fa-minus-square')) { + onDelete(postId); + } else if (targetContains(e, 'fa-plus-square')) { + onAdd(postId); + } else { + // refactor 해야함 + route(`${documentsUrl}/${postId}`); + } + }); + }; + this.render(); } export default NavbarDocumentList; diff --git a/src/Navbar/NavbarHeader.js b/src/Navbar/NavbarHeader.js index d833a085..7f0de55a 100644 --- a/src/Navbar/NavbarHeader.js +++ b/src/Navbar/NavbarHeader.js @@ -5,35 +5,35 @@ import { documentsUrl } from '../utils/util.js'; import { addHeaderMethod } from '../utils/optionsMethod.js'; function NavbarHeader({ target, initialState }) { - isNew(new.target); + isNew(new.target); - const header = createElement('div'); - header.className = 'header'; - this.state = initialState; + const header = createElement('div'); + header.className = 'header'; + this.state = initialState; - this.render = () => { - header.innerHTML = ` - ${this.state.text} - - - `; - target.appendChild(header); - }; + this.render = () => { + header.innerHTML = ` + ${this.state.text} + + + `; + target.appendChild(header); + }; - const onClickHeader = () => { - header.addEventListener('click', async (e) => { - const homeBtn = targetClosest(e, '.home-btn'); - if (homeBtn) { - route('/'); - } else { - const createPost = await addHeaderMethod(documentsUrl); - route(`${documentsUrl}/${createPost.id}`); - } - }); - }; - this.render(); + const onClickHeader = () => { + header.addEventListener('click', async (e) => { + const homeBtn = targetClosest(e, '.home-btn'); + if (homeBtn) { + route('/'); + } else { + const createPost = await addHeaderMethod(documentsUrl); + route(`${documentsUrl}/${createPost.id}`); + } + }); + }; + this.render(); - onClickHeader(); + onClickHeader(); } export default NavbarHeader; diff --git a/src/style/ui/modules/editor.css b/src/style/ui/modules/editor.css index 86e2a78e..d934017d 100644 --- a/src/style/ui/modules/editor.css +++ b/src/style/ui/modules/editor.css @@ -1,42 +1,45 @@ .app { - display: flex; - height: 100vh; + display: flex; + height: 100vh; } .content { - width: 100%; - height: 70%; - border: none; - outline: none; - overflow: auto; - font-size: 20px; - display: flex; - justify-content: space-around; - margin-top: 5%; - /*-ms-overflow-style: none;*/ + width: 100%; + height: 70%; + border: none; + outline: none; + overflow: auto; + font-size: 20px; + display: flex; + justify-content: space-around; + margin-top: 5%; + /*-ms-overflow-style: none;*/ } .content ::-webkit-scrollbar { - display: none; - height: 100em; + display: none; + height: 100em; } .editor { - width: 60%; + width: 60%; } .title { - width: 100%; - display: block; - border: none; - outline: none; - font-size: 38px; + width: 100%; + display: block; + border: none; + outline: none; + font-size: 38px; } .add { - width: 25px; + width: 25px; } .editor-content { - height: 100vh; + height: 60vh; +} + +.editor-documents { } diff --git a/src/utils/optionsMethod.js b/src/utils/optionsMethod.js index adc59edb..32627c59 100644 --- a/src/utils/optionsMethod.js +++ b/src/utils/optionsMethod.js @@ -2,45 +2,45 @@ import { request } from './api.js'; import { documentsUrl } from './util.js'; export const putTitleMethod = (id, title) => { - return request(`${documentsUrl}/${id}`, { - method: 'PUT', - body: JSON.stringify({ - title: title, - }), - }); + return request(`${documentsUrl}/${id}`, { + method: 'PUT', + body: JSON.stringify({ + title: title, + }), + }); }; export const putContentMethod = (id, content) => { - return request(`${documentsUrl}/${id}`, { - method: 'PUT', - body: JSON.stringify({ - content: content, - }), - }); + return request(`${documentsUrl}/${id}`, { + method: 'PUT', + body: JSON.stringify({ + content: content, + }), + }); }; export const addMethod = (id) => { - return request(`${documentsUrl}`, { - method: 'POST', - body: JSON.stringify({ - title: '', - parent: id, - }), - }); + return request(`${documentsUrl}`, { + method: 'POST', + body: JSON.stringify({ + title: '', + parent: id, + }), + }); }; export const addHeaderMethod = (documentsUrl) => { - return request(`${documentsUrl}`, { - method: 'POST', - boyd: JSON.stringify({ - title: '', - parent: null, - }), - }); + return request(`${documentsUrl}`, { + method: 'POST', + boyd: JSON.stringify({ + title: '', + parent: null, + }), + }); }; export const deleteMethod = (id) => { - return request(`${documentsUrl}/${id}`, { - method: 'DELETE', - }); + return request(`${documentsUrl}/${id}`, { + method: 'DELETE', + }); }; From 61f8ed4bb457d3f250cb657863d39a39f0374987 Mon Sep 17 00:00:00 2001 From: Seung-hwan285 Date: Sat, 19 Nov 2022 17:41:56 +0900 Subject: [PATCH 21/29] =?UTF-8?q?chore=20:=20tabWidth=202=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7a7ab43f..7c902b95 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "singleQuote": true, "semi": true, "useTabs": false, - "tabWidth": 4, + "tabWidth": 2, "trailingComma": "all", "printWidth": 100, "bracketSpacing": true, From b09145640b2cdbe53d1ffea6cd4688b78731797d Mon Sep 17 00:00:00 2001 From: Seung-hwan285 Date: Sat, 19 Nov 2022 17:42:59 +0900 Subject: [PATCH 22/29] =?UTF-8?q?refactor=20:=20tabWidth=202=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Editor/Editor.js | 92 +++++++++---------- src/Editor/EditorContent.js | 76 ++++++++-------- src/Editor/EditorSubContetn.js | 30 +++---- src/Editor/EditorTitle.js | 68 +++++++------- src/Navbar/Navbar.js | 148 +++++++++++++++---------------- src/Navbar/NavbarDocumentList.js | 100 ++++++++++----------- src/Navbar/NavbarHeader.js | 50 +++++------ src/utils/constant.js | 6 +- src/utils/errorHandler.js | 18 ++-- src/utils/optionsMethod.js | 58 ++++++------ 10 files changed, 323 insertions(+), 323 deletions(-) diff --git a/src/Editor/Editor.js b/src/Editor/Editor.js index d99374ee..6f49db31 100644 --- a/src/Editor/Editor.js +++ b/src/Editor/Editor.js @@ -8,53 +8,53 @@ import { documentsUrl } from '../utils/util.js'; import EditorSubContetn from './EditorSubContetn.js'; function Editor({ target, initialState }) { - isNew(new.target); - const page = createElement('section'); - page.className = 'content'; - - const editor = createElement('div'); - editor.className = 'editor'; - - this.state = initialState; - const postTitle = new EditorTitle({ - div: editor, - initialState: initialState, - - onChangeTitle: async ({ id, title }) => { - setTimeout(await putTitleMethod(id, title), 2000); - }, - }); - - const postContent = new EditorContent({ - div: editor, - initialState: initialState, - - onChangeContent: async ({ id, content }) => { - setTimeout(await putContentMethod(id, content), 2000); - }, - }); - - const postSub = new EditorSubContetn({ - div: editor, - initialState: initialState, - }); - - this.setState = async (nextState) => { - const post = await request(`${documentsUrl}/${nextState.postId}`); - isObject(post); - postTitle.setState(post); - postContent.setState(post); - postSub.setState(post); - this.render(); - }; - - this.render = () => { - // editor2.innerHTML = createSubDoucuments(); - page.appendChild(editor); - target.appendChild(page); - }; - + isNew(new.target); + const page = createElement('section'); + page.className = 'content'; + + const editor = createElement('div'); + editor.className = 'editor'; + + this.state = initialState; + const postTitle = new EditorTitle({ + div: editor, + initialState: initialState, + + onChangeTitle: async ({ id, title }) => { + setTimeout(await putTitleMethod(id, title), 2000); + }, + }); + + const postContent = new EditorContent({ + div: editor, + initialState: initialState, + + onChangeContent: async ({ id, content }) => { + setTimeout(await putContentMethod(id, content), 2000); + }, + }); + + const postSub = new EditorSubContetn({ + div: editor, + initialState: initialState, + }); + + this.setState = async (nextState) => { + const post = await request(`${documentsUrl}/${nextState.postId}`); + isObject(post); + postTitle.setState(post); + postContent.setState(post); + postSub.setState(post); this.render(); + }; + + this.render = () => { + // editor2.innerHTML = createSubDoucuments(); + page.appendChild(editor); + target.appendChild(page); + }; + + this.render(); } export default Editor; diff --git a/src/Editor/EditorContent.js b/src/Editor/EditorContent.js index a7321b65..35a8252c 100644 --- a/src/Editor/EditorContent.js +++ b/src/Editor/EditorContent.js @@ -2,46 +2,46 @@ import { createElement } from '../utils/dom.js'; import { isNew, isString } from '../utils/errorHandler.js'; function EditorContent({ div, initialState, onChangeContent }) { - isNew(new.target); - const editorContent = createElement('div'); - editorContent.className = 'editor-content'; - - this.state = initialState; - - this.setState = (nextState) => { - this.state = nextState; - const { content } = this.state; - - this.render(); - editorContent.querySelector('.content').value = content && content; - }; - - this.render = () => { - const { content } = this.state; - editorContent.innerHTML = ``; - - div.appendChild(editorContent); - }; - - const onKeyUpContent = () => { - editorContent.addEventListener('keyup', (e) => { - const { name } = e.target; - const contentValue = e.target.value; - isString(contentValue); - const nextState = { - ...this.state, - [name]: contentValue, - }; - - onChangeContent(nextState); - }); - }; + isNew(new.target); + const editorContent = createElement('div'); + editorContent.className = 'editor-content'; + + this.state = initialState; + + this.setState = (nextState) => { + this.state = nextState; + const { content } = this.state; this.render(); - onKeyUpContent(); + editorContent.querySelector('.content').value = content && content; + }; + + this.render = () => { + const { content } = this.state; + editorContent.innerHTML = ``; + + div.appendChild(editorContent); + }; + + const onKeyUpContent = () => { + editorContent.addEventListener('keyup', (e) => { + const { name } = e.target; + const contentValue = e.target.value; + isString(contentValue); + const nextState = { + ...this.state, + [name]: contentValue, + }; + + onChangeContent(nextState); + }); + }; + + this.render(); + onKeyUpContent(); } export default EditorContent; diff --git a/src/Editor/EditorSubContetn.js b/src/Editor/EditorSubContetn.js index d26007c7..9388c464 100644 --- a/src/Editor/EditorSubContetn.js +++ b/src/Editor/EditorSubContetn.js @@ -1,26 +1,26 @@ import { createElement } from '../utils/dom.js'; function EditorSubContetn({ div, initialState }) { - const editorDocuments = createElement('div'); - editorDocuments.className = 'editor-documents'; + const editorDocuments = createElement('div'); + editorDocuments.className = 'editor-documents'; - this.state = initialState; + this.state = initialState; - this.setState = (nextState) => { - this.state = nextState; - this.render(); - }; + this.setState = (nextState) => { + this.state = nextState; + this.render(); + }; - const createSubDocuments = (documents) => { - console.log(documents); - }; + const createSubDocuments = (documents) => { + console.log(documents); + }; - this.render = () => { - // editorDocuments.innerHTML = createSubDocuments(this.state); - // div.appendChild(editorDocuments); - }; + this.render = () => { + // editorDocuments.innerHTML = createSubDocuments(this.state); + // div.appendChild(editorDocuments); + }; - this.render(); + this.render(); } export default EditorSubContetn; diff --git a/src/Editor/EditorTitle.js b/src/Editor/EditorTitle.js index 53069d98..9e6b52d5 100644 --- a/src/Editor/EditorTitle.js +++ b/src/Editor/EditorTitle.js @@ -2,43 +2,43 @@ import { createElement } from '../utils/dom.js'; import { isNew, isString } from '../utils/errorHandler.js'; function EditorTitle({ div, initialState, onChangeTitle }) { - isNew(new.target); - const editorTitle = createElement('div'); - editorTitle.className = 'editor-title'; - this.state = initialState; + isNew(new.target); + const editorTitle = createElement('div'); + editorTitle.className = 'editor-title'; + this.state = initialState; - div.appendChild(editorTitle); + div.appendChild(editorTitle); - this.setState = (nextState) => { - this.state = nextState; - const { title } = this.state; - this.render(); - editorTitle.querySelector('.title').value = title && title; - }; - - this.render = () => { - const { title } = this.state; - editorTitle.innerHTML = ``; - div.appendChild(editorTitle); - }; - - const onKeyupEditorTitle = () => { - editorTitle.addEventListener('keyup', (e) => { - const { name } = e.target; - const titleValue = e.target.value; - - isString(titleValue); - - const nextState = { - ...this.state, - [name]: titleValue, - }; - - onChangeTitle(nextState); - }); - }; + this.setState = (nextState) => { + this.state = nextState; + const { title } = this.state; this.render(); - onKeyupEditorTitle(); + editorTitle.querySelector('.title').value = title && title; + }; + + this.render = () => { + const { title } = this.state; + editorTitle.innerHTML = ``; + div.appendChild(editorTitle); + }; + + const onKeyupEditorTitle = () => { + editorTitle.addEventListener('keyup', (e) => { + const { name } = e.target; + const titleValue = e.target.value; + + isString(titleValue); + + const nextState = { + ...this.state, + [name]: titleValue, + }; + + onChangeTitle(nextState); + }); + }; + this.render(); + onKeyupEditorTitle(); } export default EditorTitle; diff --git a/src/Navbar/Navbar.js b/src/Navbar/Navbar.js index 2339c339..91382d90 100644 --- a/src/Navbar/Navbar.js +++ b/src/Navbar/Navbar.js @@ -9,80 +9,80 @@ import NavbarDocumentList from './NavbarDocumentList.js'; import NavbarHeader from './NavbarHeader.js'; function Navbar({ target }) { - isNew(new.target); - const nav = createElement('nav'); - nav.className = 'sidebar'; - - new NavbarHeader({ - target: nav, - initialState: { - text: 'Notion', - }, - }); - - const documentList = new NavbarDocumentList({ - target: nav, - initialState: [], - onDelete: async (id) => { - const findCurrentId = () => { - const rootDocument = [...documentList.state]; - - while (rootDocument.length > 0) { - const cur = rootDocument.shift(); - - if (parseInt(cur.id) === parseInt(id)) { - console.log(cur); - return cur; - } - - cur.documents.forEach((el) => { - rootDocument.push(el); - }); - } - }; - // 현재 하위 document 가 3개 이상이면 하위 document 값이 삭제가 안되고 있음 - // 하위 document 2개씩만 삭제되는 현상 - - const handlerDelete = async () => { - const currentDocument = findCurrentId(); - - let que = [currentDocument]; - - const queId = [currentDocument.id]; - - while (que.length > 0) { - const current = que.shift(); - current.documents.forEach((el) => { - que.push(el); - queId.push(el.id); - }); - - for (let i of queId) { - await deleteMethod(i); - que = []; - } - } - }; - - await handlerDelete(); - route('/'); - }, - - onAdd: async (id) => { - const newPost = await addMethod(id); - route(`${documentsUrl}/${newPost.id}`); - }, - }); - - this.setState = async () => { - const posts = await request(`${documentsUrl}`); - documentList.setState(posts); - this.render(); - }; - - this.render = async () => { - target.appendChild(nav); - }; + isNew(new.target); + const nav = createElement('nav'); + nav.className = 'sidebar'; + + new NavbarHeader({ + target: nav, + initialState: { + text: 'Notion', + }, + }); + + const documentList = new NavbarDocumentList({ + target: nav, + initialState: [], + onDelete: async (id) => { + const findCurrentId = () => { + const rootDocument = [...documentList.state]; + + while (rootDocument.length > 0) { + const cur = rootDocument.shift(); + + if (parseInt(cur.id) === parseInt(id)) { + console.log(cur); + return cur; + } + + cur.documents.forEach((el) => { + rootDocument.push(el); + }); + } + }; + // 현재 하위 document 가 3개 이상이면 하위 document 값이 삭제가 안되고 있음 + // 하위 document 2개씩만 삭제되는 현상 + + const handlerDelete = async () => { + const currentDocument = findCurrentId(); + + let que = [currentDocument]; + + const queId = [currentDocument.id]; + + while (que.length > 0) { + const current = que.shift(); + current.documents.forEach((el) => { + que.push(el); + queId.push(el.id); + }); + + for (let i of queId) { + await deleteMethod(i); + que = []; + } + } + }; + + await handlerDelete(); + route('/'); + }, + + onAdd: async (id) => { + const newPost = await addMethod(id); + route(`${documentsUrl}/${newPost.id}`); + }, + }); + + this.setState = async () => { + const posts = await request(`${documentsUrl}`); + documentList.setState(posts); + this.render(); + }; + + this.render = async () => { + target.appendChild(nav); + }; } export default Navbar; diff --git a/src/Navbar/NavbarDocumentList.js b/src/Navbar/NavbarDocumentList.js index 89e2abb2..caca3797 100644 --- a/src/Navbar/NavbarDocumentList.js +++ b/src/Navbar/NavbarDocumentList.js @@ -4,70 +4,70 @@ import { route } from '../utils/route.js'; import { documentsUrl } from '../utils/util.js'; function NavbarDocumentList({ target, initialState, onDelete, onAdd }) { - isNew(new.target); - const postList = createElement('div'); + isNew(new.target); + const postList = createElement('div'); - target.appendChild(postList); + target.appendChild(postList); - this.state = initialState; + this.state = initialState; - this.setState = (nextState) => { - this.state = nextState; - this.render(); - }; + this.setState = (nextState) => { + this.state = nextState; + this.render(); + }; - this.render = () => { - postList.innerHTML = paintDocument(this.state); - onClickDocument(); - }; + this.render = () => { + postList.innerHTML = paintDocument(this.state); + onClickDocument(); + }; - const paintDocument = (docuements) => { - return ` -
        - - ${docuements - .map( + const paintDocument = (docuements) => { + return ` +
          + + ${docuements + .map( (post) => ` -
        • - -
          - -
          - ${post.title ? post.title : '제목 없음'} -
          - -
          - - +
        • + +
          + +
          + ${post.title ? post.title : '제목 없음'} +
          + +
          + + +
          - - - ${post.documents.length ? paintDocument(post.documents) : ''} + + ${post.documents.length ? paintDocument(post.documents) : ''}
        • `, - ) - .join('')} + ) + .join('')}
        `; - }; + }; - const onClickDocument = () => { - const ul = postList.querySelector('.document-list'); + const onClickDocument = () => { + const ul = postList.querySelector('.document-list'); - ul.addEventListener('click', (e) => { - const postId = targetClosest(e, 'li').id; + ul.addEventListener('click', (e) => { + const postId = targetClosest(e, 'li').id; - if (targetContains(e, 'fa-minus-square')) { - onDelete(postId); - } else if (targetContains(e, 'fa-plus-square')) { - onAdd(postId); - } else { - // refactor 해야함 - route(`${documentsUrl}/${postId}`); - } - }); - }; - this.render(); + if (targetContains(e, 'fa-minus-square')) { + onDelete(postId); + } else if (targetContains(e, 'fa-plus-square')) { + onAdd(postId); + } else { + // refactor 해야함 + route(`${documentsUrl}/${postId}`); + } + }); + }; + this.render(); } export default NavbarDocumentList; diff --git a/src/Navbar/NavbarHeader.js b/src/Navbar/NavbarHeader.js index 7f0de55a..aaca0c62 100644 --- a/src/Navbar/NavbarHeader.js +++ b/src/Navbar/NavbarHeader.js @@ -5,35 +5,35 @@ import { documentsUrl } from '../utils/util.js'; import { addHeaderMethod } from '../utils/optionsMethod.js'; function NavbarHeader({ target, initialState }) { - isNew(new.target); + isNew(new.target); - const header = createElement('div'); - header.className = 'header'; - this.state = initialState; + const header = createElement('div'); + header.className = 'header'; + this.state = initialState; - this.render = () => { - header.innerHTML = ` - ${this.state.text} - - - `; - target.appendChild(header); - }; + this.render = () => { + header.innerHTML = ` + ${this.state.text} + + + `; + target.appendChild(header); + }; - const onClickHeader = () => { - header.addEventListener('click', async (e) => { - const homeBtn = targetClosest(e, '.home-btn'); - if (homeBtn) { - route('/'); - } else { - const createPost = await addHeaderMethod(documentsUrl); - route(`${documentsUrl}/${createPost.id}`); - } - }); - }; - this.render(); + const onClickHeader = () => { + header.addEventListener('click', async (e) => { + const homeBtn = targetClosest(e, '.home-btn'); + if (homeBtn) { + route('/'); + } else { + const createPost = await addHeaderMethod(documentsUrl); + route(`${documentsUrl}/${createPost.id}`); + } + }); + }; + this.render(); - onClickHeader(); + onClickHeader(); } export default NavbarHeader; diff --git a/src/utils/constant.js b/src/utils/constant.js index ac58093b..e66fcc1c 100644 --- a/src/utils/constant.js +++ b/src/utils/constant.js @@ -1,5 +1,5 @@ export const ERROR_MESSAGE = { - NEW: 'NEW 연산자가 없습니다.', - OBJECT: '객체 타입이 아닙니다.', - STRING: '문자열 타입이 아닙니다.', + NEW: 'NEW 연산자가 없습니다.', + OBJECT: '객체 타입이 아닙니다.', + STRING: '문자열 타입이 아닙니다.', }; diff --git a/src/utils/errorHandler.js b/src/utils/errorHandler.js index 682bfbec..424468be 100644 --- a/src/utils/errorHandler.js +++ b/src/utils/errorHandler.js @@ -1,19 +1,19 @@ import { ERROR_MESSAGE } from './constant.js'; export const isNew = (target) => { - if (!target) { - throw new Error(ERROR_MESSAGE.NEW); - } + if (!target) { + throw new Error(ERROR_MESSAGE.NEW); + } }; export const isString = (title) => { - if (!title instanceof String) { - throw new Error(ERROR_MESSAGE.STRING); - } + if (!title instanceof String) { + throw new Error(ERROR_MESSAGE.STRING); + } }; export const isObject = (post) => { - if (!post instanceof Object) { - throw new Error(ERROR_MESSAGE.OBJECT); - } + if (!post instanceof Object) { + throw new Error(ERROR_MESSAGE.OBJECT); + } }; diff --git a/src/utils/optionsMethod.js b/src/utils/optionsMethod.js index 32627c59..adc59edb 100644 --- a/src/utils/optionsMethod.js +++ b/src/utils/optionsMethod.js @@ -2,45 +2,45 @@ import { request } from './api.js'; import { documentsUrl } from './util.js'; export const putTitleMethod = (id, title) => { - return request(`${documentsUrl}/${id}`, { - method: 'PUT', - body: JSON.stringify({ - title: title, - }), - }); + return request(`${documentsUrl}/${id}`, { + method: 'PUT', + body: JSON.stringify({ + title: title, + }), + }); }; export const putContentMethod = (id, content) => { - return request(`${documentsUrl}/${id}`, { - method: 'PUT', - body: JSON.stringify({ - content: content, - }), - }); + return request(`${documentsUrl}/${id}`, { + method: 'PUT', + body: JSON.stringify({ + content: content, + }), + }); }; export const addMethod = (id) => { - return request(`${documentsUrl}`, { - method: 'POST', - body: JSON.stringify({ - title: '', - parent: id, - }), - }); + return request(`${documentsUrl}`, { + method: 'POST', + body: JSON.stringify({ + title: '', + parent: id, + }), + }); }; export const addHeaderMethod = (documentsUrl) => { - return request(`${documentsUrl}`, { - method: 'POST', - boyd: JSON.stringify({ - title: '', - parent: null, - }), - }); + return request(`${documentsUrl}`, { + method: 'POST', + boyd: JSON.stringify({ + title: '', + parent: null, + }), + }); }; export const deleteMethod = (id) => { - return request(`${documentsUrl}/${id}`, { - method: 'DELETE', - }); + return request(`${documentsUrl}/${id}`, { + method: 'DELETE', + }); }; From 720cdfc4fc9ba10fd6cb5a6bcdaedc09b20a101f Mon Sep 17 00:00:00 2001 From: Seung-hwan285 Date: Sun, 20 Nov 2022 03:13:52 +0900 Subject: [PATCH 23/29] =?UTF-8?q?feat=20:=20=ED=95=98=EC=9C=84=20=EB=AC=B8?= =?UTF-8?q?=EC=84=9C=20=EB=88=84=EB=A5=B4=EB=A9=B4=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- package.json | 2 +- src/Editor/Editor.js | 106 ++++++++++++---------- src/Editor/EditorContent.js | 76 ++++++++-------- src/Editor/EditorSubContetn.js | 55 ++++++++---- src/Editor/EditorTitle.js | 68 +++++++------- src/Navbar/Navbar.js | 149 +++++++++++++++---------------- src/Navbar/NavbarDocumentList.js | 90 +++++++++---------- src/style/ui/modules/editor.css | 4 +- 9 files changed, 292 insertions(+), 260 deletions(-) diff --git a/README.md b/README.md index e60da14b..aa55dd5b 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ - [x] Editor content 부분 textarea 렌더링 했을때 2 개행 이상부터 잘려서 안나오는 현상 - [x] Editor content 일정 개행 이상 넘어가면 title 안보이는 현상 - [x] 버튼 이미지 넣어서 관리 -> 현재 text로 들어가 있음 -- [ ] 편집기 하단에는 Documents의 하위 Document 링크를 렌더링하도록 생성 +- [x] 편집기 하단에는 Documents의 하위 Document 링크를 렌더링하도록 생성 - [ ] onDelete 리팩토링 필요 - 프로젝트 기한 diff --git a/package.json b/package.json index 7c902b95..7a7ab43f 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "singleQuote": true, "semi": true, "useTabs": false, - "tabWidth": 2, + "tabWidth": 4, "trailingComma": "all", "printWidth": 100, "bracketSpacing": true, diff --git a/src/Editor/Editor.js b/src/Editor/Editor.js index 6f49db31..46afa1e3 100644 --- a/src/Editor/Editor.js +++ b/src/Editor/Editor.js @@ -5,56 +5,70 @@ import { putContentMethod, putTitleMethod } from '../utils/optionsMethod.js'; import EditorTitle from './EditorTitle.js'; import EditorContent from './EditorContent.js'; import { documentsUrl } from '../utils/util.js'; -import EditorSubContetn from './EditorSubContetn.js'; +import EditorSubContent from './EditorSubContetn.js'; +import { route } from '../utils/route.js'; function Editor({ target, initialState }) { - isNew(new.target); - const page = createElement('section'); - page.className = 'content'; - - const editor = createElement('div'); - editor.className = 'editor'; - - this.state = initialState; - const postTitle = new EditorTitle({ - div: editor, - initialState: initialState, - - onChangeTitle: async ({ id, title }) => { - setTimeout(await putTitleMethod(id, title), 2000); - }, - }); - - const postContent = new EditorContent({ - div: editor, - initialState: initialState, - - onChangeContent: async ({ id, content }) => { - setTimeout(await putContentMethod(id, content), 2000); - }, - }); - - const postSub = new EditorSubContetn({ - div: editor, - initialState: initialState, - }); - - this.setState = async (nextState) => { - const post = await request(`${documentsUrl}/${nextState.postId}`); - isObject(post); - postTitle.setState(post); - postContent.setState(post); - postSub.setState(post); - this.render(); - }; + isNew(new.target); + const page = createElement('section'); + page.className = 'content'; + + const editor = createElement('div'); + editor.className = 'editor'; + + this.state = initialState; + const postTitle = new EditorTitle({ + div: editor, + initialState: initialState, + + onChangeTitle: async ({ id, title }) => { + setTimeout(await putTitleMethod(id, title), 2000); + }, + }); + + const postContent = new EditorContent({ + div: editor, + initialState: initialState, - this.render = () => { - // editor2.innerHTML = createSubDoucuments(); - page.appendChild(editor); - target.appendChild(page); - }; + onChangeContent: async ({ id, content }) => { + setTimeout(await putContentMethod(id, content), 2000); + }, + }); - this.render(); + const postSub = new EditorSubContent({ + div: editor, + initialState: initialState, + onClickSubDocument: async (id) => { + await changeUrl(id); + }, + }); + + this.setState = async (nextState) => { + const post = await request(`${documentsUrl}/${nextState.postId}`); + isObject(post); + postTitle.setState(post); + postContent.setState(post); + postSub.setState(post); + this.render(); + }; + + this.render = () => { + page.appendChild(editor); + target.appendChild(page); + }; + + const changeUrl = async (id) => { + try { + const post = await request(`${documentsUrl}/${id}`); + route(`${documentsUrl}/${post.id}`); + console.log(post); + } catch (e) { + alert('해당 문서를 찾을 수 없습니다'); + route('/'); + } + }; + + this.render(); } export default Editor; diff --git a/src/Editor/EditorContent.js b/src/Editor/EditorContent.js index 35a8252c..9fca9027 100644 --- a/src/Editor/EditorContent.js +++ b/src/Editor/EditorContent.js @@ -2,46 +2,46 @@ import { createElement } from '../utils/dom.js'; import { isNew, isString } from '../utils/errorHandler.js'; function EditorContent({ div, initialState, onChangeContent }) { - isNew(new.target); - const editorContent = createElement('div'); - editorContent.className = 'editor-content'; - - this.state = initialState; - - this.setState = (nextState) => { - this.state = nextState; - const { content } = this.state; + isNew(new.target); + const editorContent = createElement('div'); + editorContent.className = 'editor-content'; + + this.state = initialState; + + this.setState = (nextState) => { + this.state = nextState; + const { content } = this.state; + + this.render(); + editorContent.querySelector('.content').value = content && content; + }; + + this.render = () => { + const { content } = this.state; + editorContent.innerHTML = ``; + + div.appendChild(editorContent); + }; + + const onKeyUpContent = () => { + editorContent.addEventListener('keyup', (e) => { + const { name } = e.target; + const contentValue = e.target.value; + isString(contentValue); + const nextState = { + ...this.state, + [name]: contentValue, + }; + + onChangeContent(nextState); + }); + }; this.render(); - editorContent.querySelector('.content').value = content && content; - }; - - this.render = () => { - const { content } = this.state; - editorContent.innerHTML = ``; - - div.appendChild(editorContent); - }; - - const onKeyUpContent = () => { - editorContent.addEventListener('keyup', (e) => { - const { name } = e.target; - const contentValue = e.target.value; - isString(contentValue); - const nextState = { - ...this.state, - [name]: contentValue, - }; - - onChangeContent(nextState); - }); - }; - - this.render(); - onKeyUpContent(); + onKeyUpContent(); } export default EditorContent; diff --git a/src/Editor/EditorSubContetn.js b/src/Editor/EditorSubContetn.js index 9388c464..fccbdf82 100644 --- a/src/Editor/EditorSubContetn.js +++ b/src/Editor/EditorSubContetn.js @@ -1,26 +1,45 @@ -import { createElement } from '../utils/dom.js'; +import { createElement, targetClosest } from '../utils/dom.js'; -function EditorSubContetn({ div, initialState }) { - const editorDocuments = createElement('div'); - editorDocuments.className = 'editor-documents'; +function EditorSubContent({ div, initialState, onClickSubDocument }) { + const editorDocuments = createElement('div'); + editorDocuments.className = 'editor-sub-document'; - this.state = initialState; + this.state = initialState; - this.setState = (nextState) => { - this.state = nextState; - this.render(); - }; + this.setState = (nextState) => { + this.state = nextState; + this.render(); + }; + + this.render = () => { + div.appendChild(editorDocuments); - const createSubDocuments = (documents) => { - console.log(documents); - }; + const { documents } = this.state; + editorDocuments.innerHTML = paintSubDocuments(documents); + }; - this.render = () => { - // editorDocuments.innerHTML = createSubDocuments(this.state); - // div.appendChild(editorDocuments); - }; + const paintSubDocuments = (documents2) => { + if (documents2 === undefined) { + return false; + } else { + return documents2 + .map( + ({ id, title }) => ` + +
        + + ${title}
        + `, + ) + .join(''); + } + }; - this.render(); + editorDocuments.addEventListener('click', (e) => { + const subPostId = targetClosest(e, 'div').id; + onClickSubDocument(subPostId); + }); + this.render(); } -export default EditorSubContetn; +export default EditorSubContent; diff --git a/src/Editor/EditorTitle.js b/src/Editor/EditorTitle.js index 9e6b52d5..53069d98 100644 --- a/src/Editor/EditorTitle.js +++ b/src/Editor/EditorTitle.js @@ -2,43 +2,43 @@ import { createElement } from '../utils/dom.js'; import { isNew, isString } from '../utils/errorHandler.js'; function EditorTitle({ div, initialState, onChangeTitle }) { - isNew(new.target); - const editorTitle = createElement('div'); - editorTitle.className = 'editor-title'; - this.state = initialState; + isNew(new.target); + const editorTitle = createElement('div'); + editorTitle.className = 'editor-title'; + this.state = initialState; - div.appendChild(editorTitle); - - this.setState = (nextState) => { - this.state = nextState; - const { title } = this.state; - this.render(); - editorTitle.querySelector('.title').value = title && title; - }; - - this.render = () => { - const { title } = this.state; - editorTitle.innerHTML = ``; div.appendChild(editorTitle); - }; - - const onKeyupEditorTitle = () => { - editorTitle.addEventListener('keyup', (e) => { - const { name } = e.target; - const titleValue = e.target.value; - isString(titleValue); - - const nextState = { - ...this.state, - [name]: titleValue, - }; - - onChangeTitle(nextState); - }); - }; - this.render(); - onKeyupEditorTitle(); + this.setState = (nextState) => { + this.state = nextState; + const { title } = this.state; + this.render(); + editorTitle.querySelector('.title').value = title && title; + }; + + this.render = () => { + const { title } = this.state; + editorTitle.innerHTML = ``; + div.appendChild(editorTitle); + }; + + const onKeyupEditorTitle = () => { + editorTitle.addEventListener('keyup', (e) => { + const { name } = e.target; + const titleValue = e.target.value; + + isString(titleValue); + + const nextState = { + ...this.state, + [name]: titleValue, + }; + + onChangeTitle(nextState); + }); + }; + this.render(); + onKeyupEditorTitle(); } export default EditorTitle; diff --git a/src/Navbar/Navbar.js b/src/Navbar/Navbar.js index 91382d90..164ee965 100644 --- a/src/Navbar/Navbar.js +++ b/src/Navbar/Navbar.js @@ -2,87 +2,86 @@ import { isNew } from '../utils/errorHandler.js'; import { createElement } from '../utils/dom.js'; import { request } from '../utils/api.js'; import { documentsUrl } from '../utils/util.js'; - import { addMethod, deleteMethod } from '../utils/optionsMethod.js'; import { route } from '../utils/route.js'; import NavbarDocumentList from './NavbarDocumentList.js'; import NavbarHeader from './NavbarHeader.js'; function Navbar({ target }) { - isNew(new.target); - const nav = createElement('nav'); - nav.className = 'sidebar'; - - new NavbarHeader({ - target: nav, - initialState: { - text: 'Notion', - }, - }); - - const documentList = new NavbarDocumentList({ - target: nav, - initialState: [], - onDelete: async (id) => { - const findCurrentId = () => { - const rootDocument = [...documentList.state]; - - while (rootDocument.length > 0) { - const cur = rootDocument.shift(); - - if (parseInt(cur.id) === parseInt(id)) { - console.log(cur); - return cur; - } - - cur.documents.forEach((el) => { - rootDocument.push(el); - }); - } - }; - // 현재 하위 document 가 3개 이상이면 하위 document 값이 삭제가 안되고 있음 - // 하위 document 2개씩만 삭제되는 현상 - - const handlerDelete = async () => { - const currentDocument = findCurrentId(); - - let que = [currentDocument]; - - const queId = [currentDocument.id]; - - while (que.length > 0) { - const current = que.shift(); - current.documents.forEach((el) => { - que.push(el); - queId.push(el.id); - }); - - for (let i of queId) { - await deleteMethod(i); - que = []; - } - } - }; - - await handlerDelete(); - route('/'); - }, - - onAdd: async (id) => { - const newPost = await addMethod(id); - route(`${documentsUrl}/${newPost.id}`); - }, - }); - - this.setState = async () => { - const posts = await request(`${documentsUrl}`); - documentList.setState(posts); - this.render(); - }; - - this.render = async () => { - target.appendChild(nav); - }; + isNew(new.target); + const nav = createElement('nav'); + nav.className = 'sidebar'; + + new NavbarHeader({ + target: nav, + initialState: { + text: 'Notion', + }, + }); + + const documentList = new NavbarDocumentList({ + target: nav, + initialState: [], + onDelete: async (id) => { + const findCurrentId = () => { + const rootDocument = [...documentList.state]; + + while (rootDocument.length > 0) { + const cur = rootDocument.shift(); + + if (parseInt(cur.id) === parseInt(id)) { + console.log(cur); + return cur; + } + + cur.documents.forEach((el) => { + rootDocument.push(el); + }); + } + }; + // 현재 하위 document 가 3개 이상이면 하위 document 값이 삭제가 안되고 있음 + // 하위 document 2개씩만 삭제되는 현상 + + const handlerDelete = async () => { + const currentDocument = findCurrentId(); + + let que = [currentDocument]; + + const queId = [currentDocument.id]; + + while (que.length > 0) { + const current = que.shift(); + current.documents.forEach((el) => { + que.push(el); + queId.push(el.id); + }); + + for (let i of queId) { + await deleteMethod(i); + que = []; + } + } + }; + + await handlerDelete(); + route('/'); + }, + + onAdd: async (id) => { + const newPost = await addMethod(id); + route(`${documentsUrl}/${newPost.id}`); + }, + }); + + this.setState = async () => { + const posts = await request(`${documentsUrl}`); + documentList.setState(posts); + this.render(); + }; + + this.render = async () => { + target.appendChild(nav); + }; } export default Navbar; diff --git a/src/Navbar/NavbarDocumentList.js b/src/Navbar/NavbarDocumentList.js index caca3797..1e86ae29 100644 --- a/src/Navbar/NavbarDocumentList.js +++ b/src/Navbar/NavbarDocumentList.js @@ -4,39 +4,39 @@ import { route } from '../utils/route.js'; import { documentsUrl } from '../utils/util.js'; function NavbarDocumentList({ target, initialState, onDelete, onAdd }) { - isNew(new.target); - const postList = createElement('div'); + isNew(new.target); + const postList = createElement('div'); - target.appendChild(postList); + target.appendChild(postList); - this.state = initialState; + this.state = initialState; - this.setState = (nextState) => { - this.state = nextState; - this.render(); - }; + this.setState = (nextState) => { + this.state = nextState; + this.render(); + }; - this.render = () => { - postList.innerHTML = paintDocument(this.state); - onClickDocument(); - }; + this.render = () => { + postList.innerHTML = paintDocument(this.state); + onClickDocument(); + }; - const paintDocument = (docuements) => { - return ` -
          + const paintDocument = (docuements) => { + return ` +
            + + ${docuements + .map( + (post) => ` +
          • - ${docuements - .map( - (post) => ` -
          • - -
            - -
            - ${post.title ? post.title : '제목 없음'} -
            - -
            +
            + +
            + ${post.title ? post.title : '제목 없음'} +
            + +
            @@ -45,29 +45,29 @@ function NavbarDocumentList({ target, initialState, onDelete, onAdd }) { ${post.documents.length ? paintDocument(post.documents) : ''}
          • `, - ) - .join('')} + ) + .join('')}
          `; - }; + }; - const onClickDocument = () => { - const ul = postList.querySelector('.document-list'); + const onClickDocument = () => { + const ul = postList.querySelector('.document-list'); - ul.addEventListener('click', (e) => { - const postId = targetClosest(e, 'li').id; + ul.addEventListener('click', (e) => { + const postId = targetClosest(e, 'li').id; - if (targetContains(e, 'fa-minus-square')) { - onDelete(postId); - } else if (targetContains(e, 'fa-plus-square')) { - onAdd(postId); - } else { - // refactor 해야함 - route(`${documentsUrl}/${postId}`); - } - }); - }; - this.render(); + if (targetContains(e, 'fa-minus-square')) { + onDelete(postId); + } else if (targetContains(e, 'fa-plus-square')) { + onAdd(postId); + } else { + // refactor 해야함 + route(`${documentsUrl}/${postId}`); + } + }); + }; + this.render(); } export default NavbarDocumentList; diff --git a/src/style/ui/modules/editor.css b/src/style/ui/modules/editor.css index d934017d..ae730cd4 100644 --- a/src/style/ui/modules/editor.css +++ b/src/style/ui/modules/editor.css @@ -38,8 +38,8 @@ } .editor-content { - height: 60vh; + height: 40vh; } -.editor-documents { +.editor-sub-document { } From 0aa64508a575acf6174212f64ac57c32c72b627f Mon Sep 17 00:00:00 2001 From: Seung-hwan285 Date: Sun, 20 Nov 2022 17:39:57 +0900 Subject: [PATCH 24/29] =?UTF-8?q?refactor:=20EditorSubContent=20=EC=9D=B4?= =?UTF-8?q?=EB=B2=A4=ED=8A=B8=20=ED=95=A8=EC=88=98=20=EB=B6=84=EB=A6=AC,?= =?UTF-8?q?=EB=84=A4=EC=9D=B4=EB=B0=8D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Editor/EditorSubContetn.js | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/Editor/EditorSubContetn.js b/src/Editor/EditorSubContetn.js index fccbdf82..a93e6057 100644 --- a/src/Editor/EditorSubContetn.js +++ b/src/Editor/EditorSubContetn.js @@ -18,14 +18,14 @@ function EditorSubContent({ div, initialState, onClickSubDocument }) { editorDocuments.innerHTML = paintSubDocuments(documents); }; - const paintSubDocuments = (documents2) => { - if (documents2 === undefined) { + const paintSubDocuments = (documents) => { + if (documents === undefined) { return false; } else { - return documents2 + return documents .map( ({ id, title }) => ` - +
          ${title}
          @@ -35,11 +35,15 @@ function EditorSubContent({ div, initialState, onClickSubDocument }) { } }; - editorDocuments.addEventListener('click', (e) => { - const subPostId = targetClosest(e, 'div').id; - onClickSubDocument(subPostId); - }); + const onClickEditorSubDocument = () => { + editorDocuments.addEventListener('click', (e) => { + const subPostId = targetClosest(e, 'div').id; + onClickSubDocument(subPostId); + }); + }; + this.render(); + onClickEditorSubDocument(); } export default EditorSubContent; From 634e1a9af6434f9a21287689cac403640902646f Mon Sep 17 00:00:00 2001 From: Seung-hwan285 Date: Sun, 20 Nov 2022 17:44:09 +0900 Subject: [PATCH 25/29] =?UTF-8?q?refactor:=20reset.css=20=EB=AA=A8?= =?UTF-8?q?=EB=93=88=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Editor/Editor.js | 2 +- ...ditorSubContetn.js => EditorSubContent.js} | 11 +- src/style/index.css | 137 ------------------ src/style/ui/index.css | 1 + src/style/ui/modules/reset.css | 136 +++++++++++++++++ 5 files changed, 142 insertions(+), 145 deletions(-) rename src/Editor/{EditorSubContetn.js => EditorSubContent.js} (80%) create mode 100644 src/style/ui/modules/reset.css diff --git a/src/Editor/Editor.js b/src/Editor/Editor.js index 46afa1e3..6e8c5055 100644 --- a/src/Editor/Editor.js +++ b/src/Editor/Editor.js @@ -5,8 +5,8 @@ import { putContentMethod, putTitleMethod } from '../utils/optionsMethod.js'; import EditorTitle from './EditorTitle.js'; import EditorContent from './EditorContent.js'; import { documentsUrl } from '../utils/util.js'; -import EditorSubContent from './EditorSubContetn.js'; import { route } from '../utils/route.js'; +import EditorSubContent from './EditorSubContent.js'; function Editor({ target, initialState }) { isNew(new.target); diff --git a/src/Editor/EditorSubContetn.js b/src/Editor/EditorSubContent.js similarity index 80% rename from src/Editor/EditorSubContetn.js rename to src/Editor/EditorSubContent.js index a93e6057..946c661d 100644 --- a/src/Editor/EditorSubContetn.js +++ b/src/Editor/EditorSubContent.js @@ -35,15 +35,12 @@ function EditorSubContent({ div, initialState, onClickSubDocument }) { } }; - const onClickEditorSubDocument = () => { - editorDocuments.addEventListener('click', (e) => { - const subPostId = targetClosest(e, 'div').id; - onClickSubDocument(subPostId); - }); - }; + editorDocuments.addEventListener('click', (e) => { + const subPostId = targetClosest(e, 'div').id; + onClickSubDocument(subPostId); + }); this.render(); - onClickEditorSubDocument(); } export default EditorSubContent; diff --git a/src/style/index.css b/src/style/index.css index 04dce738..086f7b00 100644 --- a/src/style/index.css +++ b/src/style/index.css @@ -1,138 +1 @@ @import 'ui/index.css'; - -/* Reset Browser */ -* { - margin: 0; - padding: 0; - box-sizing: border-box; -} -html, -body, -div, -span, -applet, -object, -iframe, -h1, -h2, -h3, -h4, -h5, -h6, -p, -blockquote, -pre, -a, -abbr, -acronym, -address, -big, -cite, -code, -del, -dfn, -em, -img, -ins, -kbd, -q, -s, -samp, -small, -strike, -strong, -sub, -sup, -tt, -var, -b, -u, -i, -center, -dl, -dt, -dd, -ol, -fieldset, -form, -label, -legend, -table, -caption, -tbody, -tfoot, -thead, -tr, -th, -td, -article, -aside, -canvas, -details, -embed, -figure, -figcaption, -footer, -header, -hgroup, -menu, -nav, -output, -ruby, -section, -summary, -time, -mark, -audio, -video { - margin: 0; - padding: 0; - border: 0; - font-size: 100%; - font: inherit; - vertical-align: baseline; -} - -/* HTML5 display-role reset for browsers */ -article, -aside, -details, -figcaption, -figure, -footer, -header, -hgroup, -menu, -nav, -section { - display: block; -} -body { - line-height: 1; -} -ol, -ul { - list-style: none; -} -blockquote, -q { - quotes: none; -} -blockquote:before, -blockquote:after, -q:before, -q:after { - content: ''; - content: none; -} -table { - border-collapse: collapse; - border-spacing: 0; -} -input:focus { - outline: none; -} -a { - color: inherit; - text-decoration: none; -} diff --git a/src/style/ui/index.css b/src/style/ui/index.css index dd48ffe7..d8354840 100644 --- a/src/style/ui/index.css +++ b/src/style/ui/index.css @@ -1,2 +1,3 @@ @import 'modules/navbar.css'; @import 'modules/editor.css'; +@import 'modules/reset.css'; diff --git a/src/style/ui/modules/reset.css b/src/style/ui/modules/reset.css new file mode 100644 index 00000000..e44f2d21 --- /dev/null +++ b/src/style/ui/modules/reset.css @@ -0,0 +1,136 @@ +/* Reset Browser */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} +html, +body, +div, +span, +applet, +object, +iframe, +h1, +h2, +h3, +h4, +h5, +h6, +p, +blockquote, +pre, +a, +abbr, +acronym, +address, +big, +cite, +code, +del, +dfn, +em, +img, +ins, +kbd, +q, +s, +samp, +small, +strike, +strong, +sub, +sup, +tt, +var, +b, +u, +i, +center, +dl, +dt, +dd, +ol, +fieldset, +form, +label, +legend, +table, +caption, +tbody, +tfoot, +thead, +tr, +th, +td, +article, +aside, +canvas, +details, +embed, +figure, +figcaption, +footer, +header, +hgroup, +menu, +nav, +output, +ruby, +section, +summary, +time, +mark, +audio, +video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; +} + +/* HTML5 display-role reset for browsers */ +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +menu, +nav, +section { + display: block; +} +body { + line-height: 1; +} +ol, +ul { + list-style: none; +} +blockquote, +q { + quotes: none; +} +blockquote:before, +blockquote:after, +q:before, +q:after { + content: ''; + content: none; +} +table { + border-collapse: collapse; + border-spacing: 0; +} +input:focus { + outline: none; +} +a { + color: inherit; + text-decoration: none; +} From 5f652f4f7c6fab56d43608997326c688d89f5ac2 Mon Sep 17 00:00:00 2001 From: Seung-hwan285 Date: Sun, 20 Nov 2022 17:48:02 +0900 Subject: [PATCH 26/29] =?UTF-8?q?feat:=20EditorSubContent=20title=20?= =?UTF-8?q?=EB=B9=84=EC=96=B4=EC=9E=88=EC=9D=84=EB=95=8C=20=20=EC=A0=9C?= =?UTF-8?q?=EB=AA=A9=EC=97=86=EC=9D=8C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Editor/EditorSubContent.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/Editor/EditorSubContent.js b/src/Editor/EditorSubContent.js index 946c661d..c8873544 100644 --- a/src/Editor/EditorSubContent.js +++ b/src/Editor/EditorSubContent.js @@ -28,19 +28,22 @@ function EditorSubContent({ div, initialState, onClickSubDocument }) {
          - ${title}
          + ${title ? title : '제목없음'} `, ) .join(''); } }; - editorDocuments.addEventListener('click', (e) => { - const subPostId = targetClosest(e, 'div').id; - onClickSubDocument(subPostId); - }); + const onClickEditorSubDocument = () => { + editorDocuments.addEventListener('click', (e) => { + const subPostId = targetClosest(e, 'div').id; + onClickSubDocument(subPostId); + }); + }; this.render(); + onClickEditorSubDocument(); } export default EditorSubContent; From 95ba0cc447a8362755b2110939ffe67bf8b60c16 Mon Sep 17 00:00:00 2001 From: Seung-hwan285 Date: Sun, 27 Nov 2022 01:52:26 +0900 Subject: [PATCH 27/29] =?UTF-8?q?refactor=20:=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=EB=A6=AC=EB=B7=B0=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 8 ++- package.json | 2 +- src/App.js | 42 ++++++------- src/Editor/Editor.js | 101 ++++++++++++++++--------------- src/Editor/EditorContent.js | 64 ++++++++++---------- src/Editor/EditorSubContent.js | 86 +++++++++++++------------- src/Editor/EditorTitle.js | 70 ++++++++++----------- src/Navbar/NavbarDocumentList.js | 69 +++++++++++---------- src/style/index.css | 4 ++ src/utils/constant.js | 1 + src/utils/dom.js | 8 +-- src/utils/errorHandler.js | 2 +- src/utils/util.js | 2 + 13 files changed, 235 insertions(+), 224 deletions(-) diff --git a/index.html b/index.html index 8694c145..809daa56 100644 --- a/index.html +++ b/index.html @@ -1,8 +1,14 @@ - + Title + diff --git a/package.json b/package.json index 7a7ab43f..7c902b95 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "singleQuote": true, "semi": true, "useTabs": false, - "tabWidth": 4, + "tabWidth": 2, "trailingComma": "all", "printWidth": 100, "bracketSpacing": true, diff --git a/src/App.js b/src/App.js index 91456888..5ebfd03f 100644 --- a/src/App.js +++ b/src/App.js @@ -4,31 +4,31 @@ import { initRouter } from './utils/route.js'; import Editor from './Editor/Editor.js'; function App({ target }) { - const navbarPage = new Navbar({ target }); - const postEditPage = new Editor({ - target, - initialState: { - title: '', - content: '', - }, - }); + const navbarPage = new Navbar({ target }); + const postEditPage = new Editor({ + target, + initialState: { + title: '', + content: '', + }, + }); - this.route = async () => { - target.innerHTML = ''; - const { pathname } = location; + this.route = async () => { + const { pathname } = location; - if (pathname === '/') { - navbarPage.setState(); - } else if (pathname.indexOf(`${documentsUrl}/`) === 0) { - const [, , postId] = pathname.split('/'); + if (pathname === '/') { + target.innerHTML = ''; + navbarPage.setState(); + } else if (pathname.indexOf(`${documentsUrl}/`) === 0) { + const [, , postId] = pathname.split('/'); - await navbarPage.setState(); - await postEditPage.setState({ postId }); - } - }; + await navbarPage.setState(); + await postEditPage.setState({ postId }); + } + }; - this.route(); - initRouter(() => this.route()); + this.route(); + initRouter(() => this.route()); } export default App; diff --git a/src/Editor/Editor.js b/src/Editor/Editor.js index 6e8c5055..1ef50c99 100644 --- a/src/Editor/Editor.js +++ b/src/Editor/Editor.js @@ -7,68 +7,69 @@ import EditorContent from './EditorContent.js'; import { documentsUrl } from '../utils/util.js'; import { route } from '../utils/route.js'; import EditorSubContent from './EditorSubContent.js'; +import { ERROR_MESSAGE } from '../utils/constant.js'; function Editor({ target, initialState }) { - isNew(new.target); - const page = createElement('section'); - page.className = 'content'; + isNew(new.target); + const page = createElement('section'); + page.className = 'content'; - const editor = createElement('div'); - editor.className = 'editor'; + const editor = createElement('div'); + editor.className = 'editor'; - this.state = initialState; - const postTitle = new EditorTitle({ - div: editor, - initialState: initialState, + this.state = initialState; - onChangeTitle: async ({ id, title }) => { - setTimeout(await putTitleMethod(id, title), 2000); - }, - }); + const postTitle = new EditorTitle({ + div: editor, + initialState: initialState, - const postContent = new EditorContent({ - div: editor, - initialState: initialState, + onChangeTitle: async ({ id, title }) => { + setTimeout(await putTitleMethod(id, title), 2000); + }, + }); - onChangeContent: async ({ id, content }) => { - setTimeout(await putContentMethod(id, content), 2000); - }, - }); + const postContent = new EditorContent({ + div: editor, + initialState: initialState, - const postSub = new EditorSubContent({ - div: editor, - initialState: initialState, - onClickSubDocument: async (id) => { - await changeUrl(id); - }, - }); + onChangeContent: async ({ id, content }) => { + setTimeout(await putContentMethod(id, content), 2000); + }, + }); - this.setState = async (nextState) => { - const post = await request(`${documentsUrl}/${nextState.postId}`); - isObject(post); - postTitle.setState(post); - postContent.setState(post); - postSub.setState(post); - this.render(); - }; + const postSub = new EditorSubContent({ + div: editor, + initialState: initialState, + onClickSubDocument: async (id) => { + await changeUrl(id); + }, + }); - this.render = () => { - page.appendChild(editor); - target.appendChild(page); - }; + this.setState = async (nextState) => { + const post = await request(`${documentsUrl}/${nextState.postId}`); + isObject(post); + postTitle.setState(post); + postContent.setState(post); + postSub.setState(post); + render(); + }; - const changeUrl = async (id) => { - try { - const post = await request(`${documentsUrl}/${id}`); - route(`${documentsUrl}/${post.id}`); - console.log(post); - } catch (e) { - alert('해당 문서를 찾을 수 없습니다'); - route('/'); - } - }; + const render = () => { + page.appendChild(editor); + target.appendChild(page); + }; - this.render(); + const changeUrl = async (id) => { + try { + const post = await request(`${documentsUrl}/${id}`); + route(`${documentsUrl}/${post.id}`); + } catch (e) { + alert(ERROR_MESSAGE.EMPTY); + route('/'); + } + }; + + render(); } export default Editor; diff --git a/src/Editor/EditorContent.js b/src/Editor/EditorContent.js index 9fca9027..1b5a36e4 100644 --- a/src/Editor/EditorContent.js +++ b/src/Editor/EditorContent.js @@ -2,46 +2,46 @@ import { createElement } from '../utils/dom.js'; import { isNew, isString } from '../utils/errorHandler.js'; function EditorContent({ div, initialState, onChangeContent }) { - isNew(new.target); - const editorContent = createElement('div'); - editorContent.className = 'editor-content'; + isNew(new.target); + const editorContent = createElement('div'); + editorContent.className = 'editor-content'; - this.state = initialState; + this.state = initialState; - this.setState = (nextState) => { - this.state = nextState; - const { content } = this.state; + this.setState = (nextState) => { + this.state = nextState; + const { content } = this.state; - this.render(); - editorContent.querySelector('.content').value = content && content; - }; + render(); + editorContent.querySelector('.content').value = content && content; + }; - this.render = () => { - const { content } = this.state; - editorContent.innerHTML = ``; - div.appendChild(editorContent); - }; - - const onKeyUpContent = () => { - editorContent.addEventListener('keyup', (e) => { - const { name } = e.target; - const contentValue = e.target.value; - isString(contentValue); - const nextState = { - ...this.state, - [name]: contentValue, - }; - - onChangeContent(nextState); - }); - }; - - this.render(); - onKeyUpContent(); + div.appendChild(editorContent); + }; + + const onKeyUpContent = () => { + editorContent.addEventListener('keyup', (e) => { + const { name } = e.target; + const contentValue = e.target.value; + isString(contentValue); + const nextState = { + ...this.state, + [name]: contentValue, + }; + + onChangeContent(nextState); + }); + }; + + render(); + onKeyUpContent(); } export default EditorContent; diff --git a/src/Editor/EditorSubContent.js b/src/Editor/EditorSubContent.js index c8873544..f37921ab 100644 --- a/src/Editor/EditorSubContent.js +++ b/src/Editor/EditorSubContent.js @@ -1,49 +1,49 @@ import { createElement, targetClosest } from '../utils/dom.js'; function EditorSubContent({ div, initialState, onClickSubDocument }) { - const editorDocuments = createElement('div'); - editorDocuments.className = 'editor-sub-document'; - - this.state = initialState; - - this.setState = (nextState) => { - this.state = nextState; - this.render(); - }; - - this.render = () => { - div.appendChild(editorDocuments); - - const { documents } = this.state; - editorDocuments.innerHTML = paintSubDocuments(documents); - }; - - const paintSubDocuments = (documents) => { - if (documents === undefined) { - return false; - } else { - return documents - .map( - ({ id, title }) => ` - -
          - - ${title ? title : '제목없음'}
          - `, - ) - .join(''); - } - }; - - const onClickEditorSubDocument = () => { - editorDocuments.addEventListener('click', (e) => { - const subPostId = targetClosest(e, 'div').id; - onClickSubDocument(subPostId); - }); - }; - - this.render(); - onClickEditorSubDocument(); + const editorDocuments = createElement('div'); + editorDocuments.className = 'editor-sub-document'; + + this.state = initialState; + + this.setState = (nextState) => { + this.state = nextState; + render(); + }; + + const render = () => { + div.appendChild(editorDocuments); + + const { documents } = this.state; + editorDocuments.innerHTML = paintSubDocuments(documents); + }; + + const paintSubDocuments = (documents) => { + if (documents === undefined) { + return false; + } else { + return documents + .map( + ({ id, title }) => ` + +
          + + ${title ? title : '제목없음'}
          + `, + ) + .join(''); + } + }; + + const onClickEditorSubDocument = () => { + editorDocuments.addEventListener('click', (e) => { + const subPostId = targetClosest(e, 'div').id; + onClickSubDocument(subPostId); + }); + }; + + render(); + onClickEditorSubDocument(); } export default EditorSubContent; diff --git a/src/Editor/EditorTitle.js b/src/Editor/EditorTitle.js index 53069d98..44f58ef2 100644 --- a/src/Editor/EditorTitle.js +++ b/src/Editor/EditorTitle.js @@ -2,43 +2,43 @@ import { createElement } from '../utils/dom.js'; import { isNew, isString } from '../utils/errorHandler.js'; function EditorTitle({ div, initialState, onChangeTitle }) { - isNew(new.target); - const editorTitle = createElement('div'); - editorTitle.className = 'editor-title'; - this.state = initialState; - + isNew(new.target); + const editorTitle = createElement('div'); + editorTitle.className = 'editor-title'; + this.state = initialState; + + div.appendChild(editorTitle); + + this.setState = (nextState) => { + this.state = nextState; + const { title } = this.state; + render(); + editorTitle.querySelector('.title').value = title && title; + }; + + const render = () => { + const { title } = this.state; + editorTitle.innerHTML = ``; div.appendChild(editorTitle); + }; + + const onKeyupEditorTitle = () => { + editorTitle.addEventListener('keyup', (e) => { + const { name } = e.target; + const titleValue = e.target.value; + + isString(titleValue); + + const nextState = { + ...this.state, + [name]: titleValue, + }; - this.setState = (nextState) => { - this.state = nextState; - const { title } = this.state; - this.render(); - editorTitle.querySelector('.title').value = title && title; - }; - - this.render = () => { - const { title } = this.state; - editorTitle.innerHTML = ``; - div.appendChild(editorTitle); - }; - - const onKeyupEditorTitle = () => { - editorTitle.addEventListener('keyup', (e) => { - const { name } = e.target; - const titleValue = e.target.value; - - isString(titleValue); - - const nextState = { - ...this.state, - [name]: titleValue, - }; - - onChangeTitle(nextState); - }); - }; - this.render(); - onKeyupEditorTitle(); + onChangeTitle(nextState); + }); + }; + render(); + onKeyupEditorTitle(); } export default EditorTitle; diff --git a/src/Navbar/NavbarDocumentList.js b/src/Navbar/NavbarDocumentList.js index 1e86ae29..37f64058 100644 --- a/src/Navbar/NavbarDocumentList.js +++ b/src/Navbar/NavbarDocumentList.js @@ -1,33 +1,33 @@ import { createElement, targetClosest, targetContains } from '../utils/dom.js'; import { isNew } from '../utils/errorHandler.js'; import { route } from '../utils/route.js'; -import { documentsUrl } from '../utils/util.js'; +import { addBtnElement, deleteBtnElement, documentsUrl } from '../utils/util.js'; function NavbarDocumentList({ target, initialState, onDelete, onAdd }) { - isNew(new.target); - const postList = createElement('div'); + isNew(new.target); + const postList = createElement('div'); - target.appendChild(postList); + target.appendChild(postList); - this.state = initialState; + this.state = initialState; - this.setState = (nextState) => { - this.state = nextState; - this.render(); - }; + this.setState = (nextState) => { + this.state = nextState; + this.render(); + }; - this.render = () => { - postList.innerHTML = paintDocument(this.state); - onClickDocument(); - }; + this.render = () => { + postList.innerHTML = paintDocument(this.state); + onClickDocument(); + }; - const paintDocument = (docuements) => { - return ` + const paintDocument = (docuements) => { + return `
            ${docuements - .map( - (post) => ` + .map( + (post) => `
          • @@ -45,29 +45,28 @@ function NavbarDocumentList({ target, initialState, onDelete, onAdd }) { ${post.documents.length ? paintDocument(post.documents) : ''}
          • `, - ) - .join('')} + ) + .join('')}
          `; - }; + }; - const onClickDocument = () => { - const ul = postList.querySelector('.document-list'); + const onClickDocument = () => { + const ul = postList.querySelector('.document-list'); - ul.addEventListener('click', (e) => { - const postId = targetClosest(e, 'li').id; + ul.addEventListener('click', (e) => { + const postId = targetClosest(e, 'li').id; - if (targetContains(e, 'fa-minus-square')) { - onDelete(postId); - } else if (targetContains(e, 'fa-plus-square')) { - onAdd(postId); - } else { - // refactor 해야함 - route(`${documentsUrl}/${postId}`); - } - }); - }; - this.render(); + if (targetContains(e, deleteBtnElement)) { + onDelete(postId); + } else if (targetContains(e, addBtnElement)) { + onAdd(postId); + } else { + route(`${documentsUrl}/${postId}`); + } + }); + }; + this.render(); } export default NavbarDocumentList; diff --git a/src/style/index.css b/src/style/index.css index 086f7b00..480be69d 100644 --- a/src/style/index.css +++ b/src/style/index.css @@ -1 +1,5 @@ @import 'ui/index.css'; +html { + visibility: visible; + opacity: 1; +} diff --git a/src/utils/constant.js b/src/utils/constant.js index e66fcc1c..865b3b78 100644 --- a/src/utils/constant.js +++ b/src/utils/constant.js @@ -2,4 +2,5 @@ export const ERROR_MESSAGE = { NEW: 'NEW 연산자가 없습니다.', OBJECT: '객체 타입이 아닙니다.', STRING: '문자열 타입이 아닙니다.', + EMPTY: '해당 문서를 찾을 수 없습니다', }; diff --git a/src/utils/dom.js b/src/utils/dom.js index 17cd3234..337f5ea9 100644 --- a/src/utils/dom.js +++ b/src/utils/dom.js @@ -1,5 +1,3 @@ -export const createElement=(e)=>document.createElement(e); -export const $ =(e)=>document.querySelector(e); -export const targetClosest=(e,str)=>e.target.closest(str); -export const targetContains=(e,str)=>e.target.classList.contains(str); - +export const createElement = (e) => document.createElement(e); +export const targetClosest = (e, str) => e.target.closest(str); +export const targetContains = (e, str) => e.target.classList.contains(str); diff --git a/src/utils/errorHandler.js b/src/utils/errorHandler.js index 424468be..23fc757b 100644 --- a/src/utils/errorHandler.js +++ b/src/utils/errorHandler.js @@ -7,7 +7,7 @@ export const isNew = (target) => { }; export const isString = (title) => { - if (!title instanceof String) { + if (typeof title !== 'string') { throw new Error(ERROR_MESSAGE.STRING); } }; diff --git a/src/utils/util.js b/src/utils/util.js index d0bcec8f..0415ff6e 100644 --- a/src/utils/util.js +++ b/src/utils/util.js @@ -1,2 +1,4 @@ export const documentsUrl = '/documents'; export const ROUTE_CHANGE_NAME = 'route-change'; +export const deleteBtnElement = 'fa-minus-square'; +export const addBtnElement = 'fa-plus-square'; From fd8744ed50283067c224dc30217385269d17b554 Mon Sep 17 00:00:00 2001 From: Seung-hwan285 Date: Sun, 27 Nov 2022 01:55:01 +0900 Subject: [PATCH 28/29] =?UTF-8?q?docs=20:=20README=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index aa55dd5b..961ff3e9 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,8 @@ - [x] 버튼 이미지 넣어서 관리 -> 현재 text로 들어가 있음 - [x] 편집기 하단에는 Documents의 하위 Document 링크를 렌더링하도록 생성 - [ ] onDelete 리팩토링 필요 +- [ ] 화면 깜빡거리는 현상 +- [ ] 디바운스 적용 - 프로젝트 기한 - 프로젝트 수행 기간 : 2022년 11월 8일(화) ~ 2022년 11월 16일(수) From 1c4d05f6521adea39bc99a1a7087b9c0c0ccade8 Mon Sep 17 00:00:00 2001 From: Seung-hwan285 Date: Wed, 30 Nov 2022 20:30:07 +0900 Subject: [PATCH 29/29] =?UTF-8?q?refactor=20:=20render=20this=20=EB=B0=94?= =?UTF-8?q?=EC=9D=B8=EB=94=A9=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Navbar/NavbarDocumentList.js | 6 +++--- src/Navbar/NavbarHeader.js | 5 ++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/Navbar/NavbarDocumentList.js b/src/Navbar/NavbarDocumentList.js index 37f64058..58133906 100644 --- a/src/Navbar/NavbarDocumentList.js +++ b/src/Navbar/NavbarDocumentList.js @@ -13,10 +13,10 @@ function NavbarDocumentList({ target, initialState, onDelete, onAdd }) { this.setState = (nextState) => { this.state = nextState; - this.render(); + render(); }; - this.render = () => { + const render = () => { postList.innerHTML = paintDocument(this.state); onClickDocument(); }; @@ -66,7 +66,7 @@ function NavbarDocumentList({ target, initialState, onDelete, onAdd }) { } }); }; - this.render(); + render(); } export default NavbarDocumentList; diff --git a/src/Navbar/NavbarHeader.js b/src/Navbar/NavbarHeader.js index aaca0c62..322f0024 100644 --- a/src/Navbar/NavbarHeader.js +++ b/src/Navbar/NavbarHeader.js @@ -11,7 +11,7 @@ function NavbarHeader({ target, initialState }) { header.className = 'header'; this.state = initialState; - this.render = () => { + const render = () => { header.innerHTML = ` ${this.state.text} @@ -31,8 +31,7 @@ function NavbarHeader({ target, initialState }) { } }); }; - this.render(); - + render(); onClickHeader(); }