From 6d86425cd90d45c454069331ea0a06fd4ef59c30 Mon Sep 17 00:00:00 2001 From: Hosek Na Date: Mon, 20 Jan 2020 14:22:05 +0900 Subject: [PATCH 01/31] feat: Init mission1 Copy origin files to this branch. --- mission001/hsna7024/css/style.css | 334 ++++++++++++++++++++++++++++++ mission001/hsna7024/index.html | 61 ++++++ 2 files changed, 395 insertions(+) create mode 100644 mission001/hsna7024/css/style.css create mode 100644 mission001/hsna7024/index.html diff --git a/mission001/hsna7024/css/style.css b/mission001/hsna7024/css/style.css new file mode 100644 index 0000000..14a905e --- /dev/null +++ b/mission001/hsna7024/css/style.css @@ -0,0 +1,334 @@ +html, +body { + margin: 0; + padding: 10px; +} + +button { + margin: 0; + padding: 0; + border: 0; + background: none; + font-size: 100%; + vertical-align: baseline; + font-family: inherit; + font-weight: inherit; + color: inherit; + -webkit-appearance: none; + appearance: none; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +body { + font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif; + line-height: 1.4em; + background: #f5f5f5; + color: #4d4d4d; + min-width: 230px; + max-width: 550px; + margin: 0 auto; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + font-weight: 300; +} + +:focus { + outline: 0; +} + +.hidden { + display: none; +} + +.todoapp { + background: #fff; + margin: 130px 0 40px 0; + position: relative; + box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), + 0 25px 50px 0 rgba(0, 0, 0, 0.1); +} + +.todoapp input::-webkit-input-placeholder { + font-style: italic; + font-weight: 300; + color: #e6e6e6; +} + +.todoapp h1 { + position: absolute; + top: -125px; + width: 100%; + font-size: 60px; + text-align: center; + color: dimgray; + font-weight: 100; + font-family: Helvetica Neue, Helvetica, Arial, sans-serif; +} + +.new-todo, +.edit { + position: relative; + margin: 0; + width: 100%; + font-size: 24px; + font-family: inherit; + font-weight: inherit; + line-height: 1.4em; + border: 0; + color: inherit; + padding: 6px; + box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2); + box-sizing: border-box; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.new-todo { + padding: 16px 16px 16px 60px; + border: none; + background: rgba(0, 0, 0, 0.003); + box-shadow: inset 0 -2px 1px rgba(0,0,0,0.03); +} + +.main { + position: relative; + z-index: 2; + border-top: 1px solid #e6e6e6; +} + +.toggle-all { + width: 1px; + height: 1px; + border: none; + opacity: 0; + position: absolute; + right: 100%; + bottom: 100%; +} + +.toggle-all + label { + width: 60px; + height: 34px; + font-size: 0; + position: absolute; + top: -52px; + left: -13px; + -webkit-transform: rotate(90deg); + transform: rotate(90deg); +} + +.toggle-all + label:before { + content: '❯'; + font-size: 22px; + color: #e6e6e6; + padding: 10px 27px 10px 27px; +} + +.toggle-all:checked + label:before { + color: #737373; +} + +.todo-list { + margin: 0; + padding: 0; + list-style: none; +} + +.todo-list li { + position: relative; + font-size: 24px; + border-bottom: 1px solid #ededed; +} + +.todo-list li:last-child { + border-bottom: none; +} + +.todo-list li.editing { + border-bottom: none; + padding: 0; +} + +.todo-list li.editing .edit { + display: block; + width: calc(100% - 43px); + padding: 12px 16px; + margin: 0 0 0 43px; +} + +.todo-list li.editing .view { + display: none; +} + +.todo-list li .toggle { + text-align: center; + width: 40px; + height: auto; + position: absolute; + top: 0; + bottom: 0; + margin: auto 0; + border: none; + -webkit-appearance: none; + appearance: none; +} + +.todo-list li .toggle { + opacity: 0; +} + +.todo-list li .toggle + label { + background-image: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23ededed%22%20stroke-width%3D%223%22/%3E%3C/svg%3E'); + background-repeat: no-repeat; + background-position: center left; +} + +.todo-list li .toggle:checked + label { + background-image: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23bddad5%22%20stroke-width%3D%223%22/%3E%3Cpath%20fill%3D%22%235dc2af%22%20d%3D%22M72%2025L42%2071%2027%2056l-4%204%2020%2020%2034-52z%22/%3E%3C/svg%3E'); +} + +.todo-list li label { + word-break: break-all; + padding: 15px 15px 15px 60px; + display: block; + line-height: 1.2; + transition: color 0.4s; +} + +.todo-list li.completed label { + color: #d9d9d9; + text-decoration: line-through; +} + +.todo-list li .destroy { + display: none; + position: absolute; + top: 0; + right: 10px; + bottom: 0; + width: 40px; + height: 40px; + margin: auto 0; + font-size: 30px; + color: #cc9a9a; + margin-bottom: 11px; + transition: color 0.2s ease-out; + cursor: pointer; +} + +.todo-list li .destroy:hover { + color: #af5b5e; +} + +.todo-list li .destroy:after { + content: '×'; +} + +.todo-list li:hover .destroy { + display: block; +} + +.todo-list li .edit { + display: none; +} + +.todo-list li.editing:last-child { + margin-bottom: -1px; +} + +.count-container { + color: #777; + padding: 10px 15px; + height: 20px; + text-align: center; + border-top: 1px solid #e6e6e6; +} + +.count-container:before { + content: ''; + position: absolute; + right: 0; + bottom: 0; + left: 0; + height: 50px; + overflow: hidden; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), + 0 8px 0 -3px #f6f6f6, + 0 9px 1px -3px rgba(0, 0, 0, 0.2), + 0 16px 0 -6px #f6f6f6, + 0 17px 2px -6px rgba(0, 0, 0, 0.2); +} + +.todo-count { + float: left; + text-align: left; +} + +.todo-count strong { + font-weight: 300; +} + +.filters { + margin: 0; + padding: 0; + list-style: none; + position: absolute; + right: 0; + left: 0; +} + +.filters li { + display: inline; +} + +.filters li a { + color: inherit; + margin: 3px; + padding: 3px 7px; + text-decoration: none; + border: 1px solid transparent; + border-radius: 3px; +} + +.filters li a:hover { + border-color: rgba(175, 47, 47, 0.1); +} + +.filters li a.selected { + border-color: rgba(175, 47, 47, 0.2); +} + +.clear-completed, html .clear-completed:active { + float: right; + position: relative; + line-height: 20px; + text-decoration: none; + cursor: pointer; +} + +.clear-completed:hover { + text-decoration: underline; +} + +.info { + margin: 65px auto 0; + color: #bfbfbf; + font-size: 10px; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + text-align: center; +} + +.info p { + line-height: 1; +} + +.info a { + color: inherit; + text-decoration: none; + font-weight: 400; +} + +.info a:hover { + text-decoration: underline; +} diff --git a/mission001/hsna7024/index.html b/mission001/hsna7024/index.html new file mode 100644 index 0000000..b1180c7 --- /dev/null +++ b/mission001/hsna7024/index.html @@ -0,0 +1,61 @@ + + + + + + 이벤트 - TODOS + + + +
+
+

TODOS

+ +
+
+ +
    +
  • +
    + + + +
    + +
  • +
  • +
    + + + +
    + +
  • +
  • +
    + + + +
    + +
  • +
+
+
+ 0 + +
+
+ + + From 0e6d7327e0cc9c04419eab0de5ffcd56a3e11cd1 Mon Sep 17 00:00:00 2001 From: Hosek Na Date: Mon, 20 Jan 2020 15:34:00 +0900 Subject: [PATCH 02/31] feat: Create 'TodoList' component --- mission001/hsna7024/js/TodoList.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 mission001/hsna7024/js/TodoList.js diff --git a/mission001/hsna7024/js/TodoList.js b/mission001/hsna7024/js/TodoList.js new file mode 100644 index 0000000..d829968 --- /dev/null +++ b/mission001/hsna7024/js/TodoList.js @@ -0,0 +1,24 @@ +export default function TodoList(params) { + const $target = params.$target; + let data = params.data || []; + + this.setState = nextData => { + data = nextData; + this.render(); + }; + + this.render = () => { + $target.innerHTML = data + .map((todo, index) => { + return `
  • +
    + + + +
  • `; + }) + .join(""); + }; + + this.render(); +} From 654233f446f56d8b596f9d24e7453c4b342d9761 Mon Sep 17 00:00:00 2001 From: Hosek Na Date: Mon, 20 Jan 2020 15:34:29 +0900 Subject: [PATCH 03/31] feat: Create 'App' component --- mission001/hsna7024/index.html | 2 +- mission001/hsna7024/js/App.js | 23 +++++++++++++++++++++++ mission001/hsna7024/js/main.js | 22 ++++++++++++++++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 mission001/hsna7024/js/App.js create mode 100644 mission001/hsna7024/js/main.js diff --git a/mission001/hsna7024/index.html b/mission001/hsna7024/index.html index b1180c7..b2a621a 100644 --- a/mission001/hsna7024/index.html +++ b/mission001/hsna7024/index.html @@ -56,6 +56,6 @@

    TODOS

    - + diff --git a/mission001/hsna7024/js/App.js b/mission001/hsna7024/js/App.js new file mode 100644 index 0000000..e7816f3 --- /dev/null +++ b/mission001/hsna7024/js/App.js @@ -0,0 +1,23 @@ +import TodoList from "./TodoList.js"; + +export default function App(params) { + const $targetTodoList = params.$targetTodoList; + let data = params.data || []; + + const todoList = new TodoList({ + $target: $targetTodoList, + data + }); + + this.setState = nextData => { + data = nextData; + todoList.setState(data); + this.render(); + }; + + this.render = () => { + todoList.render(); + }; + + this.render(); +} diff --git a/mission001/hsna7024/js/main.js b/mission001/hsna7024/js/main.js new file mode 100644 index 0000000..ab66e46 --- /dev/null +++ b/mission001/hsna7024/js/main.js @@ -0,0 +1,22 @@ +import App from "./App.js"; + +const data = [ + { + content: "새로운 타이틀" + }, + { + content: "완료된 타이틀" + }, + { + content: "완료된 타이틀" + } +]; + +const init = () => { + const app = new App({ + $targetTodoList: document.querySelector("#todo-list"), + data + }); +}; + +init(); From db44dc626e8a46b87387367ff623b8b4effbd6f4 Mon Sep 17 00:00:00 2001 From: Hosek Na Date: Mon, 20 Jan 2020 15:48:06 +0900 Subject: [PATCH 04/31] feat: Create 'TodoInput' component --- mission001/hsna7024/js/App.js | 13 ++++++++++++- mission001/hsna7024/js/TodoInput.js | 12 ++++++++++++ mission001/hsna7024/js/main.js | 1 + 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 mission001/hsna7024/js/TodoInput.js diff --git a/mission001/hsna7024/js/App.js b/mission001/hsna7024/js/App.js index e7816f3..a348f0d 100644 --- a/mission001/hsna7024/js/App.js +++ b/mission001/hsna7024/js/App.js @@ -1,7 +1,8 @@ import TodoList from "./TodoList.js"; +import TodoInput from "./TodoInput.js"; export default function App(params) { - const $targetTodoList = params.$targetTodoList; + const { $targetTodoList, $targetTodoInput } = params; let data = params.data || []; const todoList = new TodoList({ @@ -9,6 +10,16 @@ export default function App(params) { data }); + const todoInput = new TodoInput({ + $target: $targetTodoInput, + onKeyEnter: content => { + data.push({ + content + }); + this.render(); + } + }); + this.setState = nextData => { data = nextData; todoList.setState(data); diff --git a/mission001/hsna7024/js/TodoInput.js b/mission001/hsna7024/js/TodoInput.js new file mode 100644 index 0000000..1bc55ad --- /dev/null +++ b/mission001/hsna7024/js/TodoInput.js @@ -0,0 +1,12 @@ +export default function TodoInput(params) { + const { $target, onKeyEnter } = params; + + $target.addEventListener("keydown", e => { + const ENTER_KEY_CODE = 13; + + if (e.keyCode === ENTER_KEY_CODE) { + onKeyEnter($target.value); + $target.value = ""; + } + }); +} diff --git a/mission001/hsna7024/js/main.js b/mission001/hsna7024/js/main.js index ab66e46..fd1bba8 100644 --- a/mission001/hsna7024/js/main.js +++ b/mission001/hsna7024/js/main.js @@ -15,6 +15,7 @@ const data = [ const init = () => { const app = new App({ $targetTodoList: document.querySelector("#todo-list"), + $targetTodoInput: document.querySelector("#new-todo-title"), data }); }; From 54ce9d63434c1928d975af5ed9666de83519b922 Mon Sep 17 00:00:00 2001 From: Hosek Na Date: Mon, 20 Jan 2020 15:50:34 +0900 Subject: [PATCH 05/31] refactor: Use destructing in todolist --- mission001/hsna7024/js/TodoList.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mission001/hsna7024/js/TodoList.js b/mission001/hsna7024/js/TodoList.js index d829968..23a4c82 100644 --- a/mission001/hsna7024/js/TodoList.js +++ b/mission001/hsna7024/js/TodoList.js @@ -1,5 +1,5 @@ export default function TodoList(params) { - const $target = params.$target; + const { $target } = params; let data = params.data || []; this.setState = nextData => { From 5c52283b7805301cabf251c9b90c757344a581e7 Mon Sep 17 00:00:00 2001 From: Hosek Na Date: Mon, 20 Jan 2020 16:45:58 +0900 Subject: [PATCH 06/31] feat: Add toggling in todolist Todolist is toggled when it is clicked. it means "completed todo" --- mission001/hsna7024/js/TodoList.js | 18 +++++++++++++++++- mission001/hsna7024/js/main.js | 9 ++++++--- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/mission001/hsna7024/js/TodoList.js b/mission001/hsna7024/js/TodoList.js index 23a4c82..8f296d2 100644 --- a/mission001/hsna7024/js/TodoList.js +++ b/mission001/hsna7024/js/TodoList.js @@ -2,6 +2,14 @@ export default function TodoList(params) { const { $target } = params; let data = params.data || []; + $target.addEventListener("click", e => { + if (e.target.className === "toggle") { + const { id } = e.toElement.parentElement.parentElement.dataset + data[id].isCompleted = e.toElement.checked + this.render(); + } + }); + this.setState = nextData => { data = nextData; this.render(); @@ -10,7 +18,15 @@ export default function TodoList(params) { this.render = () => { $target.innerHTML = data .map((todo, index) => { - return `
  • + return todo.isCompleted + ? `
  • +
    + + + +
  • ` + : + `
  • diff --git a/mission001/hsna7024/js/main.js b/mission001/hsna7024/js/main.js index fd1bba8..fd0bacf 100644 --- a/mission001/hsna7024/js/main.js +++ b/mission001/hsna7024/js/main.js @@ -2,13 +2,16 @@ import App from "./App.js"; const data = [ { - content: "새로운 타이틀" + content: "새로운 타이틀", + isCompleted: false }, { - content: "완료된 타이틀" + content: "완료된 타이틀", + isCompleted: true }, { - content: "완료된 타이틀" + content: "완료된 타이틀", + isCompleted: true } ]; From 13996266ae2d059547cd8861bdcdd3805b628e54 Mon Sep 17 00:00:00 2001 From: Hosek Na Date: Mon, 20 Jan 2020 17:04:44 +0900 Subject: [PATCH 07/31] feat: Add remove todos When 'X' button is clicked, it is removed --- mission001/hsna7024/js/TodoList.js | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/mission001/hsna7024/js/TodoList.js b/mission001/hsna7024/js/TodoList.js index 8f296d2..93b5e07 100644 --- a/mission001/hsna7024/js/TodoList.js +++ b/mission001/hsna7024/js/TodoList.js @@ -4,8 +4,14 @@ export default function TodoList(params) { $target.addEventListener("click", e => { if (e.target.className === "toggle") { - const { id } = e.toElement.parentElement.parentElement.dataset - data[id].isCompleted = e.toElement.checked + const { id } = e.toElement.parentElement.parentElement.dataset; + data[id].isCompleted = e.toElement.checked; + this.render(); + } + + if (e.target.className === "destroy") { + const { id } = e.toElement.parentElement.parentElement.dataset; + data.splice(id, 1); this.render(); } }); @@ -19,14 +25,13 @@ export default function TodoList(params) { $target.innerHTML = data .map((todo, index) => { return todo.isCompleted - ? `
  • + ? `
  • ` - : - `
  • + : `
  • From ac8662c7937cb2feffa4b60101deea94b94de987 Mon Sep 17 00:00:00 2001 From: Hosek Na Date: Mon, 20 Jan 2020 22:00:30 +0900 Subject: [PATCH 08/31] feat: Add editing todo existed User can modify todos when it was double clicked. --- mission001/hsna7024/js/TodoList.js | 53 ++++++++++++++++++++++-------- mission001/hsna7024/js/main.js | 9 +++-- 2 files changed, 46 insertions(+), 16 deletions(-) diff --git a/mission001/hsna7024/js/TodoList.js b/mission001/hsna7024/js/TodoList.js index 93b5e07..395cca2 100644 --- a/mission001/hsna7024/js/TodoList.js +++ b/mission001/hsna7024/js/TodoList.js @@ -5,6 +5,7 @@ export default function TodoList(params) { $target.addEventListener("click", e => { if (e.target.className === "toggle") { const { id } = e.toElement.parentElement.parentElement.dataset; + console.log(e.toElement.checked); data[id].isCompleted = e.toElement.checked; this.render(); } @@ -16,6 +17,32 @@ export default function TodoList(params) { } }); + $target.addEventListener("dblclick", e => { + if (e.target.className === "label") { + const { id } = e.toElement.parentElement.parentElement.dataset; + data[id].onEdit = true; + this.render(); + } + }); + + $target.addEventListener("keydown", e => { + if (e.target.className === "edit") { + const ENTER_KEY_CODE = 13; + const ESC_KEY_CODE = 27; + if (e.keyCode === ENTER_KEY_CODE) { + const { id } = e.target.parentElement.dataset; + data[id].content = e.target.value; + data[id].onEdit = false; + this.render(); + } + if (e.keyCode === ESC_KEY_CODE) { + const { id } = e.target.parentElement.dataset; + data[id].onEdit = false; + this.render(); + } + } + }); + this.setState = nextData => { data = nextData; this.render(); @@ -24,19 +51,19 @@ export default function TodoList(params) { this.render = () => { $target.innerHTML = data .map((todo, index) => { - return todo.isCompleted - ? `
  • -
    - - - -
  • ` - : `
  • -
    - - - -
  • `; + const contentHtmlString = `
    + + +
    + `; + const completedClassName = todo.isCompleted + ? `class = "completed"` + : ""; + const editingClassName = todo.onEdit ? `class = "editing"` : ""; + + return `
  • ${contentHtmlString}
  • `; }) .join(""); }; diff --git a/mission001/hsna7024/js/main.js b/mission001/hsna7024/js/main.js index fd0bacf..d172f65 100644 --- a/mission001/hsna7024/js/main.js +++ b/mission001/hsna7024/js/main.js @@ -3,15 +3,18 @@ import App from "./App.js"; const data = [ { content: "새로운 타이틀", - isCompleted: false + isCompleted: false, + onEdit: false }, { content: "완료된 타이틀", - isCompleted: true + isCompleted: true, + onEdit: false }, { content: "완료된 타이틀", - isCompleted: true + isCompleted: true, + onEdit: false } ]; From 957e3e938981bed37d9daede33fb2427d52d0c07 Mon Sep 17 00:00:00 2001 From: Hosek Na Date: Mon, 20 Jan 2020 23:18:44 +0900 Subject: [PATCH 09/31] feat: Create 'TodoCount' component --- mission001/hsna7024/js/App.js | 10 +++++++++- mission001/hsna7024/js/TodoCount.js | 13 +++++++++++++ mission001/hsna7024/js/main.js | 1 + 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 mission001/hsna7024/js/TodoCount.js diff --git a/mission001/hsna7024/js/App.js b/mission001/hsna7024/js/App.js index a348f0d..82dabf5 100644 --- a/mission001/hsna7024/js/App.js +++ b/mission001/hsna7024/js/App.js @@ -1,8 +1,9 @@ import TodoList from "./TodoList.js"; import TodoInput from "./TodoInput.js"; +import TodoCount from "./TodoCount.js"; export default function App(params) { - const { $targetTodoList, $targetTodoInput } = params; + const { $targetTodoList, $targetTodoInput, $targetTodoCount } = params; let data = params.data || []; const todoList = new TodoList({ @@ -20,14 +21,21 @@ export default function App(params) { } }); + const todoCount = new TodoCount({ + $target: $targetTodoCount, + data + }) + this.setState = nextData => { data = nextData; todoList.setState(data); + todoCount.setState(data); this.render(); }; this.render = () => { todoList.render(); + todoCount.render(); }; this.render(); diff --git a/mission001/hsna7024/js/TodoCount.js b/mission001/hsna7024/js/TodoCount.js new file mode 100644 index 0000000..6c493f8 --- /dev/null +++ b/mission001/hsna7024/js/TodoCount.js @@ -0,0 +1,13 @@ +export default function TodoCount(params) { + const { $target } = params; + const data = params.data || []; + + this.setState = nextData => { + data = nextData; + this.render(); + }; + + this.render = () => { + $target.innerHTML = `총 ${data.length} 개`; + }; +} diff --git a/mission001/hsna7024/js/main.js b/mission001/hsna7024/js/main.js index d172f65..1a8df33 100644 --- a/mission001/hsna7024/js/main.js +++ b/mission001/hsna7024/js/main.js @@ -22,6 +22,7 @@ const init = () => { const app = new App({ $targetTodoList: document.querySelector("#todo-list"), $targetTodoInput: document.querySelector("#new-todo-title"), + $targetTodoCount: document.querySelector(".todo-count"), data }); }; From 83917e25ac803e7b34d8639324e94082823530f9 Mon Sep 17 00:00:00 2001 From: Hosek Na Date: Mon, 20 Jan 2020 23:28:36 +0900 Subject: [PATCH 10/31] refactor: Modfiy toggling todo Use toggleTodo function. --- mission001/hsna7024/js/App.js | 8 ++++++-- mission001/hsna7024/js/TodoList.js | 6 ++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/mission001/hsna7024/js/App.js b/mission001/hsna7024/js/App.js index 82dabf5..71a7a5e 100644 --- a/mission001/hsna7024/js/App.js +++ b/mission001/hsna7024/js/App.js @@ -8,7 +8,11 @@ export default function App(params) { const todoList = new TodoList({ $target: $targetTodoList, - data + data, + toggleTodo: id => { + data[id].isCompleted = !data[id].isCompleted; + this.render(); + } }); const todoInput = new TodoInput({ @@ -24,7 +28,7 @@ export default function App(params) { const todoCount = new TodoCount({ $target: $targetTodoCount, data - }) + }); this.setState = nextData => { data = nextData; diff --git a/mission001/hsna7024/js/TodoList.js b/mission001/hsna7024/js/TodoList.js index 395cca2..06df658 100644 --- a/mission001/hsna7024/js/TodoList.js +++ b/mission001/hsna7024/js/TodoList.js @@ -1,13 +1,11 @@ export default function TodoList(params) { - const { $target } = params; + const { $target, toggleTodo } = params; let data = params.data || []; $target.addEventListener("click", e => { if (e.target.className === "toggle") { const { id } = e.toElement.parentElement.parentElement.dataset; - console.log(e.toElement.checked); - data[id].isCompleted = e.toElement.checked; - this.render(); + toggleTodo(id); } if (e.target.className === "destroy") { From bbde6db815a22d76546fddd1337da33f32bc9ac2 Mon Sep 17 00:00:00 2001 From: Hosek Na Date: Mon, 20 Jan 2020 23:31:34 +0900 Subject: [PATCH 11/31] refactor: Modfiy removing todo Use removeTodo function. --- mission001/hsna7024/js/App.js | 4 ++++ mission001/hsna7024/js/TodoList.js | 9 +++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/mission001/hsna7024/js/App.js b/mission001/hsna7024/js/App.js index 71a7a5e..7e4a810 100644 --- a/mission001/hsna7024/js/App.js +++ b/mission001/hsna7024/js/App.js @@ -12,6 +12,10 @@ export default function App(params) { toggleTodo: id => { data[id].isCompleted = !data[id].isCompleted; this.render(); + }, + removeTodo: id => { + data.splice(id, 1); + this.render(); } }); diff --git a/mission001/hsna7024/js/TodoList.js b/mission001/hsna7024/js/TodoList.js index 06df658..190ecbb 100644 --- a/mission001/hsna7024/js/TodoList.js +++ b/mission001/hsna7024/js/TodoList.js @@ -1,17 +1,14 @@ export default function TodoList(params) { - const { $target, toggleTodo } = params; + const { $target, toggleTodo, removeTodo } = params; let data = params.data || []; $target.addEventListener("click", e => { + const { id } = e.toElement.parentElement.parentElement.dataset; if (e.target.className === "toggle") { - const { id } = e.toElement.parentElement.parentElement.dataset; toggleTodo(id); } - if (e.target.className === "destroy") { - const { id } = e.toElement.parentElement.parentElement.dataset; - data.splice(id, 1); - this.render(); + removeTodo(id); } }); From 69f590e9c841969af74b25b2214150f4885656a8 Mon Sep 17 00:00:00 2001 From: Hosek Na Date: Tue, 21 Jan 2020 13:01:16 +0900 Subject: [PATCH 12/31] feat: Create 'TodoFilter' component Todos is rendered by filter --- mission001/hsna7024/js/App.js | 36 +++++++++++++++++++---- mission001/hsna7024/js/TodoCount.js | 2 +- mission001/hsna7024/js/TodoFilter.js | 20 +++++++++++++ mission001/hsna7024/js/TodoList.js | 17 +++++++---- mission001/hsna7024/js/main.js | 2 ++ mission001/hsna7024/js/utils/constants.js | 5 ++++ 6 files changed, 71 insertions(+), 11 deletions(-) create mode 100644 mission001/hsna7024/js/TodoFilter.js create mode 100644 mission001/hsna7024/js/utils/constants.js diff --git a/mission001/hsna7024/js/App.js b/mission001/hsna7024/js/App.js index 7e4a810..71422f0 100644 --- a/mission001/hsna7024/js/App.js +++ b/mission001/hsna7024/js/App.js @@ -1,10 +1,26 @@ import TodoList from "./TodoList.js"; import TodoInput from "./TodoInput.js"; import TodoCount from "./TodoCount.js"; +import TodoFilter from "./TodoFilter.js"; +import { filters } from "./utils/constants.js"; export default function App(params) { - const { $targetTodoList, $targetTodoInput, $targetTodoCount } = params; + const { + $targetTodoList, + $targetTodoInput, + $targetTodoCount, + $targetTodoFilter, + } = params; let data = params.data || []; + let filter = params.data || filters.ALL; + + const filterTodos = (todos, filter) => { + switch(filter){ + case filters.ACTIVE: return todos.filter(todo => !todo.isCompleted); + case filters.COMPLETED: return todos.filter(todo => todo.isCompleted); + default : return todos; + } + } const todoList = new TodoList({ $target: $targetTodoList, @@ -16,7 +32,9 @@ export default function App(params) { removeTodo: id => { data.splice(id, 1); this.render(); - } + }, + filter, + filterTodos }); const todoInput = new TodoInput({ @@ -34,10 +52,18 @@ export default function App(params) { data }); - this.setState = nextData => { + const todoFilter = new TodoFilter({ + $target: $targetTodoFilter, + changeFilter: nextFilter => { + this.setState(data, nextFilter); + } + }); + + this.setState = (nextData, nextFilter) => { data = nextData; - todoList.setState(data); - todoCount.setState(data); + filter = nextFilter + todoList.setState(data, filter); + todoCount.setState(filterTodos(data, filter)); this.render(); }; diff --git a/mission001/hsna7024/js/TodoCount.js b/mission001/hsna7024/js/TodoCount.js index 6c493f8..d3a0449 100644 --- a/mission001/hsna7024/js/TodoCount.js +++ b/mission001/hsna7024/js/TodoCount.js @@ -1,6 +1,6 @@ export default function TodoCount(params) { const { $target } = params; - const data = params.data || []; + let data = params.data || []; this.setState = nextData => { data = nextData; diff --git a/mission001/hsna7024/js/TodoFilter.js b/mission001/hsna7024/js/TodoFilter.js new file mode 100644 index 0000000..e70d499 --- /dev/null +++ b/mission001/hsna7024/js/TodoFilter.js @@ -0,0 +1,20 @@ +export default function TodoFilter(params) { + const { $target, changeFilter } = params; + + $target.addEventListener("click", e => { + changeFilter(e.target.className); + }); + + this.render = () => { + $target.innerHTML = ` +
  • + 전체보기 +
  • +
  • + 해야할 일 +
  • +
  • + 완료한 일 +
  • `; + }; +} diff --git a/mission001/hsna7024/js/TodoList.js b/mission001/hsna7024/js/TodoList.js index 190ecbb..0e2c1a8 100644 --- a/mission001/hsna7024/js/TodoList.js +++ b/mission001/hsna7024/js/TodoList.js @@ -1,6 +1,8 @@ export default function TodoList(params) { - const { $target, toggleTodo, removeTodo } = params; + const { $target, toggleTodo, removeTodo, filterTodos } = params; let data = params.data || []; + let filter = params.filter || ""; + let filteredData = []; $target.addEventListener("click", e => { const { id } = e.toElement.parentElement.parentElement.dataset; @@ -38,15 +40,20 @@ export default function TodoList(params) { } }); - this.setState = nextData => { - data = nextData; + filteredData = filterTodos(data, filter) + + this.setState = (nextData, nextFilter) => { + data = nextData || data; + filter = nextFilter || filter; + console.log(filter) + filteredData = filterTodos(data, filter) this.render(); }; this.render = () => { - $target.innerHTML = data + $target.innerHTML = filteredData .map((todo, index) => { - const contentHtmlString = `
    + const contentHtmlString = `
    diff --git a/mission001/hsna7024/js/main.js b/mission001/hsna7024/js/main.js index 1a8df33..b8e7363 100644 --- a/mission001/hsna7024/js/main.js +++ b/mission001/hsna7024/js/main.js @@ -23,6 +23,8 @@ const init = () => { $targetTodoList: document.querySelector("#todo-list"), $targetTodoInput: document.querySelector("#new-todo-title"), $targetTodoCount: document.querySelector(".todo-count"), + $targetTodoFilter: document.querySelector(".filters"), + filter: "all selected", data }); }; diff --git a/mission001/hsna7024/js/utils/constants.js b/mission001/hsna7024/js/utils/constants.js new file mode 100644 index 0000000..d04918f --- /dev/null +++ b/mission001/hsna7024/js/utils/constants.js @@ -0,0 +1,5 @@ +export const filters = { + ALL : "all selected", + ACTIVE : "active", + COMPLETED : "completed" +} From f3e29a1ea1cdd1ee67ece7d8977caddfce3fb57b Mon Sep 17 00:00:00 2001 From: Hosek Na Date: Tue, 21 Jan 2020 13:12:45 +0900 Subject: [PATCH 13/31] refactor: Use constants for class name --- mission001/hsna7024/js/TodoList.js | 16 +++++++++------- mission001/hsna7024/js/utils/constants.js | 15 +++++++++++---- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/mission001/hsna7024/js/TodoList.js b/mission001/hsna7024/js/TodoList.js index 0e2c1a8..a0b3612 100644 --- a/mission001/hsna7024/js/TodoList.js +++ b/mission001/hsna7024/js/TodoList.js @@ -1,3 +1,5 @@ +import { classNames } from "./utils/constants" + export default function TodoList(params) { const { $target, toggleTodo, removeTodo, filterTodos } = params; let data = params.data || []; @@ -6,16 +8,16 @@ export default function TodoList(params) { $target.addEventListener("click", e => { const { id } = e.toElement.parentElement.parentElement.dataset; - if (e.target.className === "toggle") { + if (e.target.className === classNames.TOGGLE) { toggleTodo(id); } - if (e.target.className === "destroy") { + if (e.target.className === classNames.REMOVE) { removeTodo(id); } }); $target.addEventListener("dblclick", e => { - if (e.target.className === "label") { + if (e.target.className === classNames.LABEL) { const { id } = e.toElement.parentElement.parentElement.dataset; data[id].onEdit = true; this.render(); @@ -23,7 +25,7 @@ export default function TodoList(params) { }); $target.addEventListener("keydown", e => { - if (e.target.className === "edit") { + if (e.target.className === classNames.EDIT) { const ENTER_KEY_CODE = 13; const ESC_KEY_CODE = 27; if (e.keyCode === ENTER_KEY_CODE) { @@ -40,13 +42,13 @@ export default function TodoList(params) { } }); - filteredData = filterTodos(data, filter) + filteredData = filterTodos(data, filter); this.setState = (nextData, nextFilter) => { data = nextData || data; filter = nextFilter || filter; - console.log(filter) - filteredData = filterTodos(data, filter) + console.log(filter); + filteredData = filterTodos(data, filter); this.render(); }; diff --git a/mission001/hsna7024/js/utils/constants.js b/mission001/hsna7024/js/utils/constants.js index d04918f..80c279f 100644 --- a/mission001/hsna7024/js/utils/constants.js +++ b/mission001/hsna7024/js/utils/constants.js @@ -1,5 +1,12 @@ export const filters = { - ALL : "all selected", - ACTIVE : "active", - COMPLETED : "completed" -} + ALL: "all selected", + ACTIVE: "active", + COMPLETED: "completed" +}; + +export const classNames = { + TOGGLE: "toggle", + REMOVE: "destroy", + LABEL: "label", + EDIT: "edit" +}; From 9deab847b32543afe3fe7b6eef17d64d5b355c36 Mon Sep 17 00:00:00 2001 From: Hosek Na Date: Tue, 21 Jan 2020 13:19:54 +0900 Subject: [PATCH 14/31] refactor: Use constatns key codes --- mission001/hsna7024/js/TodoList.js | 8 +++----- mission001/hsna7024/js/utils/constants.js | 5 +++++ 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/mission001/hsna7024/js/TodoList.js b/mission001/hsna7024/js/TodoList.js index a0b3612..ce0a23e 100644 --- a/mission001/hsna7024/js/TodoList.js +++ b/mission001/hsna7024/js/TodoList.js @@ -1,4 +1,4 @@ -import { classNames } from "./utils/constants" +import { classNames, keyCodes } from "./utils/constants" export default function TodoList(params) { const { $target, toggleTodo, removeTodo, filterTodos } = params; @@ -26,15 +26,13 @@ export default function TodoList(params) { $target.addEventListener("keydown", e => { if (e.target.className === classNames.EDIT) { - const ENTER_KEY_CODE = 13; - const ESC_KEY_CODE = 27; - if (e.keyCode === ENTER_KEY_CODE) { + if (e.keyCode === keyCodes.ENTER) { const { id } = e.target.parentElement.dataset; data[id].content = e.target.value; data[id].onEdit = false; this.render(); } - if (e.keyCode === ESC_KEY_CODE) { + if (e.keyCode === keyCodes.ESC) { const { id } = e.target.parentElement.dataset; data[id].onEdit = false; this.render(); diff --git a/mission001/hsna7024/js/utils/constants.js b/mission001/hsna7024/js/utils/constants.js index 80c279f..9f5fe10 100644 --- a/mission001/hsna7024/js/utils/constants.js +++ b/mission001/hsna7024/js/utils/constants.js @@ -10,3 +10,8 @@ export const classNames = { LABEL: "label", EDIT: "edit" }; + +export const keyCodes = { + ENTER: 13, + ESC: 27 +} From c2e99a940b1bc043a7a925a4a54001b08e898ef4 Mon Sep 17 00:00:00 2001 From: Hosek Na Date: Tue, 21 Jan 2020 13:38:49 +0900 Subject: [PATCH 15/31] refactor: Use html templates --- mission001/hsna7024/js/TodoFilter.js | 13 +++---------- mission001/hsna7024/js/TodoList.js | 21 +++------------------ mission001/hsna7024/js/utils/templates.js | 23 +++++++++++++++++++++++ 3 files changed, 29 insertions(+), 28 deletions(-) create mode 100644 mission001/hsna7024/js/utils/templates.js diff --git a/mission001/hsna7024/js/TodoFilter.js b/mission001/hsna7024/js/TodoFilter.js index e70d499..6a9abb5 100644 --- a/mission001/hsna7024/js/TodoFilter.js +++ b/mission001/hsna7024/js/TodoFilter.js @@ -1,3 +1,5 @@ +import { todoFilterTemplate } from "./utils/templates.js"; + export default function TodoFilter(params) { const { $target, changeFilter } = params; @@ -6,15 +8,6 @@ export default function TodoFilter(params) { }); this.render = () => { - $target.innerHTML = ` -
  • - 전체보기 -
  • -
  • - 해야할 일 -
  • -
  • - 완료한 일 -
  • `; + $target.innerHTML = todoFilterTemplate; }; } diff --git a/mission001/hsna7024/js/TodoList.js b/mission001/hsna7024/js/TodoList.js index ce0a23e..63f4c83 100644 --- a/mission001/hsna7024/js/TodoList.js +++ b/mission001/hsna7024/js/TodoList.js @@ -1,4 +1,5 @@ -import { classNames, keyCodes } from "./utils/constants" +import { classNames, keyCodes } from "./utils/constants.js"; +import { todoListTemplate } from "./utils/templates.js"; export default function TodoList(params) { const { $target, toggleTodo, removeTodo, filterTodos } = params; @@ -51,23 +52,7 @@ export default function TodoList(params) { }; this.render = () => { - $target.innerHTML = filteredData - .map((todo, index) => { - const contentHtmlString = `
    - - -
    - `; - const completedClassName = todo.isCompleted - ? `class = "completed"` - : ""; - const editingClassName = todo.onEdit ? `class = "editing"` : ""; - - return `
  • ${contentHtmlString}
  • `; - }) - .join(""); + $target.innerHTML = filteredData.map(todoListTemplate).join(""); }; this.render(); diff --git a/mission001/hsna7024/js/utils/templates.js b/mission001/hsna7024/js/utils/templates.js new file mode 100644 index 0000000..e2760cf --- /dev/null +++ b/mission001/hsna7024/js/utils/templates.js @@ -0,0 +1,23 @@ +export const todoListTemplate = (todo, index) => { + const contentHtmlString = `
    + + +
    + `; + const completedClassName = todo.isCompleted ? `class = "completed"` : ""; + const editingClassName = todo.onEdit ? `class = "editing"` : ""; + + return `
  • ${contentHtmlString}
  • `; +}; + +export const todoFilterTemplate = () => { + `
  • + 전체보기 +
  • +
  • + 해야할 일 +
  • +
  • + 완료한 일 +
  • `; +}; From eec0051e7bb41da3c9f3b0fd996f791fb4ee3a85 Mon Sep 17 00:00:00 2001 From: Hosek Na Date: Tue, 21 Jan 2020 13:58:20 +0900 Subject: [PATCH 16/31] refactor: Use constants --- mission001/hsna7024/js/TodoCount.js | 4 +++- mission001/hsna7024/js/TodoInput.js | 6 +++--- mission001/hsna7024/js/utils/templates.js | 4 ++++ 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/mission001/hsna7024/js/TodoCount.js b/mission001/hsna7024/js/TodoCount.js index d3a0449..e3160e4 100644 --- a/mission001/hsna7024/js/TodoCount.js +++ b/mission001/hsna7024/js/TodoCount.js @@ -1,3 +1,5 @@ +import { todoCountTemplate } from "./utils/templates.js"; + export default function TodoCount(params) { const { $target } = params; let data = params.data || []; @@ -8,6 +10,6 @@ export default function TodoCount(params) { }; this.render = () => { - $target.innerHTML = `총 ${data.length} 개`; + $target.innerHTML = todoCountTemplate(data.length); }; } diff --git a/mission001/hsna7024/js/TodoInput.js b/mission001/hsna7024/js/TodoInput.js index 1bc55ad..5bf0226 100644 --- a/mission001/hsna7024/js/TodoInput.js +++ b/mission001/hsna7024/js/TodoInput.js @@ -1,10 +1,10 @@ +import { keyCodes } from "./utils/constants.js"; + export default function TodoInput(params) { const { $target, onKeyEnter } = params; $target.addEventListener("keydown", e => { - const ENTER_KEY_CODE = 13; - - if (e.keyCode === ENTER_KEY_CODE) { + if (e.keyCode === keyCodes.ENTER) { onKeyEnter($target.value); $target.value = ""; } diff --git a/mission001/hsna7024/js/utils/templates.js b/mission001/hsna7024/js/utils/templates.js index e2760cf..c77334c 100644 --- a/mission001/hsna7024/js/utils/templates.js +++ b/mission001/hsna7024/js/utils/templates.js @@ -21,3 +21,7 @@ export const todoFilterTemplate = () => { 완료한 일 `; }; + +export const todoCountTemplate = length => { + return `총 ${length} 개`; +}; From e8985b65543eb30e5a478ab4d6b331cbbbead7fd Mon Sep 17 00:00:00 2001 From: Hosek Na Date: Tue, 21 Jan 2020 13:58:48 +0900 Subject: [PATCH 17/31] fix: Fix rendering todoFilter --- mission001/hsna7024/js/TodoFilter.js | 4 +++- mission001/hsna7024/js/utils/templates.js | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/mission001/hsna7024/js/TodoFilter.js b/mission001/hsna7024/js/TodoFilter.js index 6a9abb5..d9fbe56 100644 --- a/mission001/hsna7024/js/TodoFilter.js +++ b/mission001/hsna7024/js/TodoFilter.js @@ -8,6 +8,8 @@ export default function TodoFilter(params) { }); this.render = () => { - $target.innerHTML = todoFilterTemplate; + $target.innerHTML = todoFilterTemplate(); }; + + this.render(); } diff --git a/mission001/hsna7024/js/utils/templates.js b/mission001/hsna7024/js/utils/templates.js index c77334c..d4ddc15 100644 --- a/mission001/hsna7024/js/utils/templates.js +++ b/mission001/hsna7024/js/utils/templates.js @@ -11,7 +11,7 @@ export const todoListTemplate = (todo, index) => { }; export const todoFilterTemplate = () => { - `
  • + return `
  • 전체보기
  • From ef1e2a1e5a1ade1528465a0935465055f676127c Mon Sep 17 00:00:00 2001 From: Hosek Na Date: Tue, 21 Jan 2020 14:39:17 +0900 Subject: [PATCH 18/31] refactor: Modify filterTodo Modify rendering about "selected" class name. --- mission001/hsna7024/js/App.js | 24 ++++++++++++++--------- mission001/hsna7024/js/TodoFilter.js | 8 +++++++- mission001/hsna7024/js/TodoList.js | 1 - mission001/hsna7024/js/main.js | 3 ++- mission001/hsna7024/js/utils/constants.js | 2 +- mission001/hsna7024/js/utils/templates.js | 14 +++++++++---- 6 files changed, 35 insertions(+), 17 deletions(-) diff --git a/mission001/hsna7024/js/App.js b/mission001/hsna7024/js/App.js index 71422f0..b40c6c3 100644 --- a/mission001/hsna7024/js/App.js +++ b/mission001/hsna7024/js/App.js @@ -9,18 +9,21 @@ export default function App(params) { $targetTodoList, $targetTodoInput, $targetTodoCount, - $targetTodoFilter, + $targetTodoFilter } = params; let data = params.data || []; - let filter = params.data || filters.ALL; + let filter = params.filter || filters.ALL; const filterTodos = (todos, filter) => { - switch(filter){ - case filters.ACTIVE: return todos.filter(todo => !todo.isCompleted); - case filters.COMPLETED: return todos.filter(todo => todo.isCompleted); - default : return todos; + switch (filter) { + case filters.ACTIVE: + return todos.filter(todo => !todo.isCompleted); + case filters.COMPLETED: + return todos.filter(todo => todo.isCompleted); + default: + return todos; } - } + }; const todoList = new TodoList({ $target: $targetTodoList, @@ -56,20 +59,23 @@ export default function App(params) { $target: $targetTodoFilter, changeFilter: nextFilter => { this.setState(data, nextFilter); - } + }, + filter }); this.setState = (nextData, nextFilter) => { data = nextData; - filter = nextFilter + filter = nextFilter; todoList.setState(data, filter); todoCount.setState(filterTodos(data, filter)); + todoFilter.setState(filter); this.render(); }; this.render = () => { todoList.render(); todoCount.render(); + todoFilter.render(); }; this.render(); diff --git a/mission001/hsna7024/js/TodoFilter.js b/mission001/hsna7024/js/TodoFilter.js index d9fbe56..f7bc099 100644 --- a/mission001/hsna7024/js/TodoFilter.js +++ b/mission001/hsna7024/js/TodoFilter.js @@ -2,13 +2,19 @@ import { todoFilterTemplate } from "./utils/templates.js"; export default function TodoFilter(params) { const { $target, changeFilter } = params; + let filter = params.filter || ""; $target.addEventListener("click", e => { changeFilter(e.target.className); }); + this.setState = nextFilter => { + filter = nextFilter; + this.render(); + }; + this.render = () => { - $target.innerHTML = todoFilterTemplate(); + $target.innerHTML = todoFilterTemplate(filter); }; this.render(); diff --git a/mission001/hsna7024/js/TodoList.js b/mission001/hsna7024/js/TodoList.js index 63f4c83..ee5cd05 100644 --- a/mission001/hsna7024/js/TodoList.js +++ b/mission001/hsna7024/js/TodoList.js @@ -46,7 +46,6 @@ export default function TodoList(params) { this.setState = (nextData, nextFilter) => { data = nextData || data; filter = nextFilter || filter; - console.log(filter); filteredData = filterTodos(data, filter); this.render(); }; diff --git a/mission001/hsna7024/js/main.js b/mission001/hsna7024/js/main.js index b8e7363..6385ba7 100644 --- a/mission001/hsna7024/js/main.js +++ b/mission001/hsna7024/js/main.js @@ -1,4 +1,5 @@ import App from "./App.js"; +import { filters } from "./utils/constants.js"; const data = [ { @@ -24,7 +25,7 @@ const init = () => { $targetTodoInput: document.querySelector("#new-todo-title"), $targetTodoCount: document.querySelector(".todo-count"), $targetTodoFilter: document.querySelector(".filters"), - filter: "all selected", + filter: filters.ALL, data }); }; diff --git a/mission001/hsna7024/js/utils/constants.js b/mission001/hsna7024/js/utils/constants.js index 9f5fe10..e77a454 100644 --- a/mission001/hsna7024/js/utils/constants.js +++ b/mission001/hsna7024/js/utils/constants.js @@ -1,5 +1,5 @@ export const filters = { - ALL: "all selected", + ALL: "all", ACTIVE: "active", COMPLETED: "completed" }; diff --git a/mission001/hsna7024/js/utils/templates.js b/mission001/hsna7024/js/utils/templates.js index d4ddc15..4478a3f 100644 --- a/mission001/hsna7024/js/utils/templates.js +++ b/mission001/hsna7024/js/utils/templates.js @@ -1,3 +1,5 @@ +import { filters } from "./constants.js"; + export const todoListTemplate = (todo, index) => { const contentHtmlString = `
    @@ -10,15 +12,19 @@ export const todoListTemplate = (todo, index) => { return `
  • ${contentHtmlString}
  • `; }; -export const todoFilterTemplate = () => { +export const todoFilterTemplate = filter => { + const allSelected = filter === filters.ALL ? " selected" : ""; + const activeSelected = filter === filters.ACTIVE ? " selected" : ""; + const completedSelected = filter === filters.COMPLETED ? " selected" : ""; + return `
  • - 전체보기 + 전체보기
  • - 해야할 일 + 해야할 일
  • - 완료한 일 + 완료한 일
  • `; }; From f2014d0ea6b531e90a8db3957a8b031f115d3587 Mon Sep 17 00:00:00 2001 From: Hosek Na Date: Tue, 21 Jan 2020 15:05:07 +0900 Subject: [PATCH 19/31] refactor: Modfiy constants name Use name convention "map". --- mission001/hsna7024/js/App.js | 8 ++++---- mission001/hsna7024/js/TodoInput.js | 4 ++-- mission001/hsna7024/js/TodoList.js | 14 +++++++------- mission001/hsna7024/js/main.js | 4 ++-- mission001/hsna7024/js/utils/constants.js | 6 +++--- mission001/hsna7024/js/utils/templates.js | 8 ++++---- 6 files changed, 22 insertions(+), 22 deletions(-) diff --git a/mission001/hsna7024/js/App.js b/mission001/hsna7024/js/App.js index b40c6c3..facc013 100644 --- a/mission001/hsna7024/js/App.js +++ b/mission001/hsna7024/js/App.js @@ -2,7 +2,7 @@ import TodoList from "./TodoList.js"; import TodoInput from "./TodoInput.js"; import TodoCount from "./TodoCount.js"; import TodoFilter from "./TodoFilter.js"; -import { filters } from "./utils/constants.js"; +import { filterMap } from "./utils/constants.js"; export default function App(params) { const { @@ -12,13 +12,13 @@ export default function App(params) { $targetTodoFilter } = params; let data = params.data || []; - let filter = params.filter || filters.ALL; + let filter = params.filter || filterMap.ALL; const filterTodos = (todos, filter) => { switch (filter) { - case filters.ACTIVE: + case filterMap.ACTIVE: return todos.filter(todo => !todo.isCompleted); - case filters.COMPLETED: + case filterMap.COMPLETED: return todos.filter(todo => todo.isCompleted); default: return todos; diff --git a/mission001/hsna7024/js/TodoInput.js b/mission001/hsna7024/js/TodoInput.js index 5bf0226..9cb8eef 100644 --- a/mission001/hsna7024/js/TodoInput.js +++ b/mission001/hsna7024/js/TodoInput.js @@ -1,10 +1,10 @@ -import { keyCodes } from "./utils/constants.js"; +import { keyCodeMap } from "./utils/constants.js"; export default function TodoInput(params) { const { $target, onKeyEnter } = params; $target.addEventListener("keydown", e => { - if (e.keyCode === keyCodes.ENTER) { + if (e.keyCode === keyCodeMap.ENTER) { onKeyEnter($target.value); $target.value = ""; } diff --git a/mission001/hsna7024/js/TodoList.js b/mission001/hsna7024/js/TodoList.js index ee5cd05..fad5f22 100644 --- a/mission001/hsna7024/js/TodoList.js +++ b/mission001/hsna7024/js/TodoList.js @@ -1,4 +1,4 @@ -import { classNames, keyCodes } from "./utils/constants.js"; +import { classNameMap, keyCodeMap } from "./utils/constants.js"; import { todoListTemplate } from "./utils/templates.js"; export default function TodoList(params) { @@ -9,16 +9,16 @@ export default function TodoList(params) { $target.addEventListener("click", e => { const { id } = e.toElement.parentElement.parentElement.dataset; - if (e.target.className === classNames.TOGGLE) { + if (e.target.className === classNameMap.TOGGLE) { toggleTodo(id); } - if (e.target.className === classNames.REMOVE) { + if (e.target.className === classNameMap.REMOVE) { removeTodo(id); } }); $target.addEventListener("dblclick", e => { - if (e.target.className === classNames.LABEL) { + if (e.target.className === classNameMap.LABEL) { const { id } = e.toElement.parentElement.parentElement.dataset; data[id].onEdit = true; this.render(); @@ -26,14 +26,14 @@ export default function TodoList(params) { }); $target.addEventListener("keydown", e => { - if (e.target.className === classNames.EDIT) { - if (e.keyCode === keyCodes.ENTER) { + if (e.target.className === classNameMap.EDIT) { + if (e.keyCode === keyCodeMap.ENTER) { const { id } = e.target.parentElement.dataset; data[id].content = e.target.value; data[id].onEdit = false; this.render(); } - if (e.keyCode === keyCodes.ESC) { + if (e.keyCode === keyCodeMap.ESC) { const { id } = e.target.parentElement.dataset; data[id].onEdit = false; this.render(); diff --git a/mission001/hsna7024/js/main.js b/mission001/hsna7024/js/main.js index 6385ba7..98417a9 100644 --- a/mission001/hsna7024/js/main.js +++ b/mission001/hsna7024/js/main.js @@ -1,5 +1,5 @@ import App from "./App.js"; -import { filters } from "./utils/constants.js"; +import { filterMap } from "./utils/constants.js"; const data = [ { @@ -25,7 +25,7 @@ const init = () => { $targetTodoInput: document.querySelector("#new-todo-title"), $targetTodoCount: document.querySelector(".todo-count"), $targetTodoFilter: document.querySelector(".filters"), - filter: filters.ALL, + filter: filterMap.ALL, data }); }; diff --git a/mission001/hsna7024/js/utils/constants.js b/mission001/hsna7024/js/utils/constants.js index e77a454..424a4a0 100644 --- a/mission001/hsna7024/js/utils/constants.js +++ b/mission001/hsna7024/js/utils/constants.js @@ -1,17 +1,17 @@ -export const filters = { +export const filterMap = { ALL: "all", ACTIVE: "active", COMPLETED: "completed" }; -export const classNames = { +export const classNameMap = { TOGGLE: "toggle", REMOVE: "destroy", LABEL: "label", EDIT: "edit" }; -export const keyCodes = { +export const keyCodeMap = { ENTER: 13, ESC: 27 } diff --git a/mission001/hsna7024/js/utils/templates.js b/mission001/hsna7024/js/utils/templates.js index 4478a3f..7a12351 100644 --- a/mission001/hsna7024/js/utils/templates.js +++ b/mission001/hsna7024/js/utils/templates.js @@ -1,4 +1,4 @@ -import { filters } from "./constants.js"; +import { filterMap } from "./constants.js"; export const todoListTemplate = (todo, index) => { const contentHtmlString = `
    @@ -13,9 +13,9 @@ export const todoListTemplate = (todo, index) => { }; export const todoFilterTemplate = filter => { - const allSelected = filter === filters.ALL ? " selected" : ""; - const activeSelected = filter === filters.ACTIVE ? " selected" : ""; - const completedSelected = filter === filters.COMPLETED ? " selected" : ""; + const allSelected = filter === filterMap.ALL ? " selected" : ""; + const activeSelected = filter === filterMap.ACTIVE ? " selected" : ""; + const completedSelected = filter === filterMap.COMPLETED ? " selected" : ""; return `
  • 전체보기 From 370cc7c6790d75001b88829ce221a142a191dfb6 Mon Sep 17 00:00:00 2001 From: Hosek Na Date: Tue, 21 Jan 2020 15:20:14 +0900 Subject: [PATCH 20/31] refactor: Reduce duplicated code --- mission001/hsna7024/js/TodoList.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mission001/hsna7024/js/TodoList.js b/mission001/hsna7024/js/TodoList.js index fad5f22..e252fdd 100644 --- a/mission001/hsna7024/js/TodoList.js +++ b/mission001/hsna7024/js/TodoList.js @@ -27,14 +27,13 @@ export default function TodoList(params) { $target.addEventListener("keydown", e => { if (e.target.className === classNameMap.EDIT) { + const { id } = e.target.parentElement.dataset; if (e.keyCode === keyCodeMap.ENTER) { - const { id } = e.target.parentElement.dataset; data[id].content = e.target.value; data[id].onEdit = false; this.render(); } if (e.keyCode === keyCodeMap.ESC) { - const { id } = e.target.parentElement.dataset; data[id].onEdit = false; this.render(); } From b51304c431d441bb149156f9508bb694c4e00391 Mon Sep 17 00:00:00 2001 From: Hosek Na Date: Tue, 21 Jan 2020 15:38:44 +0900 Subject: [PATCH 21/31] refactor: Check target element --- mission001/hsna7024/js/TodoCount.js | 4 ++++ mission001/hsna7024/js/TodoFilter.js | 4 ++++ mission001/hsna7024/js/TodoInput.js | 4 ++++ mission001/hsna7024/js/TodoList.js | 6 +++++- mission001/hsna7024/js/utils/constants.js | 4 ++++ 5 files changed, 21 insertions(+), 1 deletion(-) diff --git a/mission001/hsna7024/js/TodoCount.js b/mission001/hsna7024/js/TodoCount.js index e3160e4..8766164 100644 --- a/mission001/hsna7024/js/TodoCount.js +++ b/mission001/hsna7024/js/TodoCount.js @@ -4,6 +4,10 @@ export default function TodoCount(params) { const { $target } = params; let data = params.data || []; + if($target === null) { + throw new Error(errorMessageMap.IS_NO_TARGET); + } + this.setState = nextData => { data = nextData; this.render(); diff --git a/mission001/hsna7024/js/TodoFilter.js b/mission001/hsna7024/js/TodoFilter.js index f7bc099..7ad735a 100644 --- a/mission001/hsna7024/js/TodoFilter.js +++ b/mission001/hsna7024/js/TodoFilter.js @@ -4,6 +4,10 @@ export default function TodoFilter(params) { const { $target, changeFilter } = params; let filter = params.filter || ""; + if($target === null) { + throw new Error(errorMessageMap.IS_NO_TARGET); + } + $target.addEventListener("click", e => { changeFilter(e.target.className); }); diff --git a/mission001/hsna7024/js/TodoInput.js b/mission001/hsna7024/js/TodoInput.js index 9cb8eef..b35127f 100644 --- a/mission001/hsna7024/js/TodoInput.js +++ b/mission001/hsna7024/js/TodoInput.js @@ -3,6 +3,10 @@ import { keyCodeMap } from "./utils/constants.js"; export default function TodoInput(params) { const { $target, onKeyEnter } = params; + if($target === null) { + throw new Error(errorMessageMap.IS_NO_TARGET); + } + $target.addEventListener("keydown", e => { if (e.keyCode === keyCodeMap.ENTER) { onKeyEnter($target.value); diff --git a/mission001/hsna7024/js/TodoList.js b/mission001/hsna7024/js/TodoList.js index e252fdd..00386e3 100644 --- a/mission001/hsna7024/js/TodoList.js +++ b/mission001/hsna7024/js/TodoList.js @@ -1,4 +1,4 @@ -import { classNameMap, keyCodeMap } from "./utils/constants.js"; +import { classNameMap, keyCodeMap, errorMessageMap } from "./utils/constants.js"; import { todoListTemplate } from "./utils/templates.js"; export default function TodoList(params) { @@ -7,6 +7,10 @@ export default function TodoList(params) { let filter = params.filter || ""; let filteredData = []; + if($target === null) { + throw new Error(errorMessageMap.IS_NO_TARGET); + } + $target.addEventListener("click", e => { const { id } = e.toElement.parentElement.parentElement.dataset; if (e.target.className === classNameMap.TOGGLE) { diff --git a/mission001/hsna7024/js/utils/constants.js b/mission001/hsna7024/js/utils/constants.js index 424a4a0..ce4e7e1 100644 --- a/mission001/hsna7024/js/utils/constants.js +++ b/mission001/hsna7024/js/utils/constants.js @@ -15,3 +15,7 @@ export const keyCodeMap = { ENTER: 13, ESC: 27 } + +export const errorMessageMap = { + IS_NO_TARGET: 'target element가 없습니다.', +} From 0672dfe001170f15ada44b54e4fe649d25c276e6 Mon Sep 17 00:00:00 2001 From: Hosek Na Date: Tue, 21 Jan 2020 15:40:46 +0900 Subject: [PATCH 22/31] refactor: Check empty value in typing --- mission001/hsna7024/js/TodoInput.js | 2 +- mission001/hsna7024/js/TodoList.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mission001/hsna7024/js/TodoInput.js b/mission001/hsna7024/js/TodoInput.js index b35127f..8cf97bf 100644 --- a/mission001/hsna7024/js/TodoInput.js +++ b/mission001/hsna7024/js/TodoInput.js @@ -8,7 +8,7 @@ export default function TodoInput(params) { } $target.addEventListener("keydown", e => { - if (e.keyCode === keyCodeMap.ENTER) { + if (e.keyCode === keyCodeMap.ENTER && $target.value) { onKeyEnter($target.value); $target.value = ""; } diff --git a/mission001/hsna7024/js/TodoList.js b/mission001/hsna7024/js/TodoList.js index 00386e3..14ab5e0 100644 --- a/mission001/hsna7024/js/TodoList.js +++ b/mission001/hsna7024/js/TodoList.js @@ -32,7 +32,7 @@ export default function TodoList(params) { $target.addEventListener("keydown", e => { if (e.target.className === classNameMap.EDIT) { const { id } = e.target.parentElement.dataset; - if (e.keyCode === keyCodeMap.ENTER) { + if (e.keyCode === keyCodeMap.ENTER && e.target.value) { data[id].content = e.target.value; data[id].onEdit = false; this.render(); From 15703f057025ffada9b40caa12f67baa4a1276d2 Mon Sep 17 00:00:00 2001 From: Hosek Na Date: Tue, 21 Jan 2020 15:56:48 +0900 Subject: [PATCH 23/31] refactor: Modfiy todoCount Get only count not todo data. --- mission001/hsna7024/js/App.js | 4 ++-- mission001/hsna7024/js/TodoCount.js | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/mission001/hsna7024/js/App.js b/mission001/hsna7024/js/App.js index facc013..91386e7 100644 --- a/mission001/hsna7024/js/App.js +++ b/mission001/hsna7024/js/App.js @@ -52,7 +52,7 @@ export default function App(params) { const todoCount = new TodoCount({ $target: $targetTodoCount, - data + count : data.length }); const todoFilter = new TodoFilter({ @@ -67,7 +67,7 @@ export default function App(params) { data = nextData; filter = nextFilter; todoList.setState(data, filter); - todoCount.setState(filterTodos(data, filter)); + todoCount.setState(filterTodos(data, filter).length); todoFilter.setState(filter); this.render(); }; diff --git a/mission001/hsna7024/js/TodoCount.js b/mission001/hsna7024/js/TodoCount.js index 8766164..eaf403e 100644 --- a/mission001/hsna7024/js/TodoCount.js +++ b/mission001/hsna7024/js/TodoCount.js @@ -2,18 +2,18 @@ import { todoCountTemplate } from "./utils/templates.js"; export default function TodoCount(params) { const { $target } = params; - let data = params.data || []; + let count = params.count || 0; if($target === null) { throw new Error(errorMessageMap.IS_NO_TARGET); } - this.setState = nextData => { - data = nextData; + this.setState = nextCount => { + count = nextCount; this.render(); }; this.render = () => { - $target.innerHTML = todoCountTemplate(data.length); + $target.innerHTML = todoCountTemplate(count); }; } From 1b2fda3f0c421c32b3ca8354e179866f0a6a17fe Mon Sep 17 00:00:00 2001 From: Hosek Na Date: Tue, 21 Jan 2020 20:35:04 +0900 Subject: [PATCH 24/31] refactor: Use key instead of keycode --- mission001/hsna7024/js/TodoInput.js | 4 ++-- mission001/hsna7024/js/TodoList.js | 6 +++--- mission001/hsna7024/js/utils/constants.js | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/mission001/hsna7024/js/TodoInput.js b/mission001/hsna7024/js/TodoInput.js index 8cf97bf..560785d 100644 --- a/mission001/hsna7024/js/TodoInput.js +++ b/mission001/hsna7024/js/TodoInput.js @@ -1,4 +1,4 @@ -import { keyCodeMap } from "./utils/constants.js"; +import { keyMap } from "./utils/constants.js"; export default function TodoInput(params) { const { $target, onKeyEnter } = params; @@ -8,7 +8,7 @@ export default function TodoInput(params) { } $target.addEventListener("keydown", e => { - if (e.keyCode === keyCodeMap.ENTER && $target.value) { + if (e.key === keyMap.ENTER && $target.value) { onKeyEnter($target.value); $target.value = ""; } diff --git a/mission001/hsna7024/js/TodoList.js b/mission001/hsna7024/js/TodoList.js index 14ab5e0..f0d6468 100644 --- a/mission001/hsna7024/js/TodoList.js +++ b/mission001/hsna7024/js/TodoList.js @@ -1,4 +1,4 @@ -import { classNameMap, keyCodeMap, errorMessageMap } from "./utils/constants.js"; +import { classNameMap, keyMap, errorMessageMap } from "./utils/constants.js"; import { todoListTemplate } from "./utils/templates.js"; export default function TodoList(params) { @@ -32,12 +32,12 @@ export default function TodoList(params) { $target.addEventListener("keydown", e => { if (e.target.className === classNameMap.EDIT) { const { id } = e.target.parentElement.dataset; - if (e.keyCode === keyCodeMap.ENTER && e.target.value) { + if (e.key === keyMap.ENTER && e.target.value) { data[id].content = e.target.value; data[id].onEdit = false; this.render(); } - if (e.keyCode === keyCodeMap.ESC) { + if (e.key === keyMap.ESC) { data[id].onEdit = false; this.render(); } diff --git a/mission001/hsna7024/js/utils/constants.js b/mission001/hsna7024/js/utils/constants.js index ce4e7e1..72d7a1d 100644 --- a/mission001/hsna7024/js/utils/constants.js +++ b/mission001/hsna7024/js/utils/constants.js @@ -11,9 +11,9 @@ export const classNameMap = { EDIT: "edit" }; -export const keyCodeMap = { - ENTER: 13, - ESC: 27 +export const keyMap = { + ENTER: "Enter", + ESC: "Escape" } export const errorMessageMap = { From 5b871bb5b2c325f5c38ff69273cc4993945d2fe6 Mon Sep 17 00:00:00 2001 From: Hosek Na Date: Sun, 9 Feb 2020 22:53:52 +0900 Subject: [PATCH 25/31] refactor: Use closest --- mission001/hsna7024/js/TodoList.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mission001/hsna7024/js/TodoList.js b/mission001/hsna7024/js/TodoList.js index f0d6468..0d323b6 100644 --- a/mission001/hsna7024/js/TodoList.js +++ b/mission001/hsna7024/js/TodoList.js @@ -12,7 +12,7 @@ export default function TodoList(params) { } $target.addEventListener("click", e => { - const { id } = e.toElement.parentElement.parentElement.dataset; + const { id } = e.target.closest("li").dataset; if (e.target.className === classNameMap.TOGGLE) { toggleTodo(id); } @@ -23,7 +23,7 @@ export default function TodoList(params) { $target.addEventListener("dblclick", e => { if (e.target.className === classNameMap.LABEL) { - const { id } = e.toElement.parentElement.parentElement.dataset; + const { id } = e.target.closest("li").dataset; data[id].onEdit = true; this.render(); } @@ -31,7 +31,7 @@ export default function TodoList(params) { $target.addEventListener("keydown", e => { if (e.target.className === classNameMap.EDIT) { - const { id } = e.target.parentElement.dataset; + const { id } = e.target.closest("li").dataset; if (e.key === keyMap.ENTER && e.target.value) { data[id].content = e.target.value; data[id].onEdit = false; From a5ea9338dba02bc78d9507112740dd406e091553 Mon Sep 17 00:00:00 2001 From: Hosek Na Date: Sun, 9 Feb 2020 22:58:30 +0900 Subject: [PATCH 26/31] refactor: Use else if --- mission001/hsna7024/js/TodoList.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mission001/hsna7024/js/TodoList.js b/mission001/hsna7024/js/TodoList.js index 0d323b6..da8e450 100644 --- a/mission001/hsna7024/js/TodoList.js +++ b/mission001/hsna7024/js/TodoList.js @@ -16,7 +16,7 @@ export default function TodoList(params) { if (e.target.className === classNameMap.TOGGLE) { toggleTodo(id); } - if (e.target.className === classNameMap.REMOVE) { + else if (e.target.className === classNameMap.REMOVE) { removeTodo(id); } }); @@ -37,7 +37,7 @@ export default function TodoList(params) { data[id].onEdit = false; this.render(); } - if (e.key === keyMap.ESC) { + else if (e.key === keyMap.ESC) { data[id].onEdit = false; this.render(); } From 51dd4f4e14f870f4d2925918b5ed49eae9084fd8 Mon Sep 17 00:00:00 2001 From: Hosek Na Date: Sun, 9 Feb 2020 23:04:43 +0900 Subject: [PATCH 27/31] refactor: Use classList.contains --- mission001/hsna7024/js/TodoList.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mission001/hsna7024/js/TodoList.js b/mission001/hsna7024/js/TodoList.js index da8e450..41e6ab1 100644 --- a/mission001/hsna7024/js/TodoList.js +++ b/mission001/hsna7024/js/TodoList.js @@ -22,7 +22,7 @@ export default function TodoList(params) { }); $target.addEventListener("dblclick", e => { - if (e.target.className === classNameMap.LABEL) { + if (e.target.classList.contains(classNameMap.LABEL)) { const { id } = e.target.closest("li").dataset; data[id].onEdit = true; this.render(); @@ -30,7 +30,7 @@ export default function TodoList(params) { }); $target.addEventListener("keydown", e => { - if (e.target.className === classNameMap.EDIT) { + if (e.target.classList.contains(classNameMap.EDIT)) { const { id } = e.target.closest("li").dataset; if (e.key === keyMap.ENTER && e.target.value) { data[id].content = e.target.value; From 08cb4db699491133315232f885ddcda341e11791 Mon Sep 17 00:00:00 2001 From: Hosek Na Date: Sun, 9 Feb 2020 23:10:35 +0900 Subject: [PATCH 28/31] refactor: Use classList.contains --- mission001/hsna7024/js/TodoList.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mission001/hsna7024/js/TodoList.js b/mission001/hsna7024/js/TodoList.js index 41e6ab1..be6fa7b 100644 --- a/mission001/hsna7024/js/TodoList.js +++ b/mission001/hsna7024/js/TodoList.js @@ -13,10 +13,10 @@ export default function TodoList(params) { $target.addEventListener("click", e => { const { id } = e.target.closest("li").dataset; - if (e.target.className === classNameMap.TOGGLE) { + if (e.target.classList.contains(classNameMap.TOGGLE)) { toggleTodo(id); } - else if (e.target.className === classNameMap.REMOVE) { + else if (e.target.classList.contains(classNameMap.REMOVE)) { removeTodo(id); } }); From 05abded4914637eb36b64d3aee022335dd6707b7 Mon Sep 17 00:00:00 2001 From: Hosek Na Date: Sun, 9 Feb 2020 23:16:38 +0900 Subject: [PATCH 29/31] refactor: Modify indent in template --- mission001/hsna7024/js/utils/templates.js | 31 +++++++++++++---------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/mission001/hsna7024/js/utils/templates.js b/mission001/hsna7024/js/utils/templates.js index 7a12351..4e02cd1 100644 --- a/mission001/hsna7024/js/utils/templates.js +++ b/mission001/hsna7024/js/utils/templates.js @@ -1,11 +1,13 @@ import { filterMap } from "./constants.js"; export const todoListTemplate = (todo, index) => { - const contentHtmlString = `
    - - -
    - `; + const contentHtmlString = ` +
    + + + +
    + `; const completedClassName = todo.isCompleted ? `class = "completed"` : ""; const editingClassName = todo.onEdit ? `class = "editing"` : ""; @@ -17,15 +19,16 @@ export const todoFilterTemplate = filter => { const activeSelected = filter === filterMap.ACTIVE ? " selected" : ""; const completedSelected = filter === filterMap.COMPLETED ? " selected" : ""; - return `
  • - 전체보기 -
  • -
  • - 해야할 일 -
  • -
  • - 완료한 일 -
  • `; + return ` +
  • + 전체보기 +
  • +
  • + 해야할 일 +
  • +
  • + 완료한 일 +
  • `; }; export const todoCountTemplate = length => { From 24e0f339be26778af88d26822251c884f68f1618 Mon Sep 17 00:00:00 2001 From: Hosek Na Date: Mon, 10 Feb 2020 00:07:13 +0900 Subject: [PATCH 30/31] refactor: Use eslint --- mission001/hsna7024/.eslintrc.json | 25 +++++++++++++++++++++++ mission001/hsna7024/js/App.js | 2 +- mission001/hsna7024/js/TodoCount.js | 3 ++- mission001/hsna7024/js/TodoFilter.js | 3 ++- mission001/hsna7024/js/TodoInput.js | 6 +++--- mission001/hsna7024/js/TodoList.js | 11 +++++----- mission001/hsna7024/js/utils/constants.js | 12 +++++------ mission001/hsna7024/js/utils/templates.js | 12 +++++------ mission001/hsna7024/package.json | 17 +++++++++++++++ 9 files changed, 67 insertions(+), 24 deletions(-) create mode 100644 mission001/hsna7024/.eslintrc.json create mode 100644 mission001/hsna7024/package.json diff --git a/mission001/hsna7024/.eslintrc.json b/mission001/hsna7024/.eslintrc.json new file mode 100644 index 0000000..85f9d3c --- /dev/null +++ b/mission001/hsna7024/.eslintrc.json @@ -0,0 +1,25 @@ +{ + "env": { + "browser": true, + "es6": true + }, + "extends": [ + "airbnb-base" + ], + "globals": { + "Atomics": "readonly", + "SharedArrayBuffer": "readonly" + }, + "parserOptions": { + "ecmaVersion": 2018, + "sourceType": "module" + }, + "rules": { + "linebreak-style": 0, + "import/extensions": 0, + "quotes": 0, + "arrow-parens": 0, + "object-curly-newline": 0, + "comma-dangle": 0 + } +} diff --git a/mission001/hsna7024/js/App.js b/mission001/hsna7024/js/App.js index 91386e7..03af786 100644 --- a/mission001/hsna7024/js/App.js +++ b/mission001/hsna7024/js/App.js @@ -52,7 +52,7 @@ export default function App(params) { const todoCount = new TodoCount({ $target: $targetTodoCount, - count : data.length + count: data.length }); const todoFilter = new TodoFilter({ diff --git a/mission001/hsna7024/js/TodoCount.js b/mission001/hsna7024/js/TodoCount.js index eaf403e..f123a62 100644 --- a/mission001/hsna7024/js/TodoCount.js +++ b/mission001/hsna7024/js/TodoCount.js @@ -1,10 +1,11 @@ import { todoCountTemplate } from "./utils/templates.js"; +import { errorMessageMap } from "./utils/constants.js"; export default function TodoCount(params) { const { $target } = params; let count = params.count || 0; - if($target === null) { + if ($target === null) { throw new Error(errorMessageMap.IS_NO_TARGET); } diff --git a/mission001/hsna7024/js/TodoFilter.js b/mission001/hsna7024/js/TodoFilter.js index 7ad735a..d142513 100644 --- a/mission001/hsna7024/js/TodoFilter.js +++ b/mission001/hsna7024/js/TodoFilter.js @@ -1,10 +1,11 @@ import { todoFilterTemplate } from "./utils/templates.js"; +import { errorMessageMap } from "./utils/constants.js"; export default function TodoFilter(params) { const { $target, changeFilter } = params; let filter = params.filter || ""; - if($target === null) { + if ($target === null) { throw new Error(errorMessageMap.IS_NO_TARGET); } diff --git a/mission001/hsna7024/js/TodoInput.js b/mission001/hsna7024/js/TodoInput.js index 560785d..a31da88 100644 --- a/mission001/hsna7024/js/TodoInput.js +++ b/mission001/hsna7024/js/TodoInput.js @@ -1,14 +1,14 @@ -import { keyMap } from "./utils/constants.js"; +import { keyMap, errorMessageMap } from "./utils/constants.js"; export default function TodoInput(params) { const { $target, onKeyEnter } = params; - if($target === null) { + if ($target === null) { throw new Error(errorMessageMap.IS_NO_TARGET); } $target.addEventListener("keydown", e => { - if (e.key === keyMap.ENTER && $target.value) { + if (e.key === keyMap.ENTER && $target.value) { onKeyEnter($target.value); $target.value = ""; } diff --git a/mission001/hsna7024/js/TodoList.js b/mission001/hsna7024/js/TodoList.js index be6fa7b..a0d45d3 100644 --- a/mission001/hsna7024/js/TodoList.js +++ b/mission001/hsna7024/js/TodoList.js @@ -2,12 +2,13 @@ import { classNameMap, keyMap, errorMessageMap } from "./utils/constants.js"; import { todoListTemplate } from "./utils/templates.js"; export default function TodoList(params) { - const { $target, toggleTodo, removeTodo, filterTodos } = params; + const { $target, toggleTodo, removeTodo, filterTodos +} = params; let data = params.data || []; let filter = params.filter || ""; let filteredData = []; - if($target === null) { + if ($target === null) { throw new Error(errorMessageMap.IS_NO_TARGET); } @@ -15,8 +16,7 @@ export default function TodoList(params) { const { id } = e.target.closest("li").dataset; if (e.target.classList.contains(classNameMap.TOGGLE)) { toggleTodo(id); - } - else if (e.target.classList.contains(classNameMap.REMOVE)) { + } else if (e.target.classList.contains(classNameMap.REMOVE)) { removeTodo(id); } }); @@ -36,8 +36,7 @@ export default function TodoList(params) { data[id].content = e.target.value; data[id].onEdit = false; this.render(); - } - else if (e.key === keyMap.ESC) { + } else if (e.key === keyMap.ESC) { data[id].onEdit = false; this.render(); } diff --git a/mission001/hsna7024/js/utils/constants.js b/mission001/hsna7024/js/utils/constants.js index 72d7a1d..0dae28e 100644 --- a/mission001/hsna7024/js/utils/constants.js +++ b/mission001/hsna7024/js/utils/constants.js @@ -1,21 +1,21 @@ export const filterMap = { ALL: "all", ACTIVE: "active", - COMPLETED: "completed" + COMPLETED: "completed", }; export const classNameMap = { TOGGLE: "toggle", REMOVE: "destroy", LABEL: "label", - EDIT: "edit" + EDIT: "edit", }; export const keyMap = { ENTER: "Enter", - ESC: "Escape" -} + ESC: "Escape", +}; export const errorMessageMap = { - IS_NO_TARGET: 'target element가 없습니다.', -} + IS_NO_TARGET: "target element가 없습니다.", +}; diff --git a/mission001/hsna7024/js/utils/templates.js b/mission001/hsna7024/js/utils/templates.js index 4e02cd1..7000a27 100644 --- a/mission001/hsna7024/js/utils/templates.js +++ b/mission001/hsna7024/js/utils/templates.js @@ -3,13 +3,15 @@ import { filterMap } from "./constants.js"; export const todoListTemplate = (todo, index) => { const contentHtmlString = `
    - +
    `; - const completedClassName = todo.isCompleted ? `class = "completed"` : ""; - const editingClassName = todo.onEdit ? `class = "editing"` : ""; + const completedClassName = todo.isCompleted ? 'class = "completed"' : ""; + const editingClassName = todo.onEdit ? 'class = "editing"' : ""; return `
  • ${contentHtmlString}
  • `; }; @@ -31,6 +33,4 @@ export const todoFilterTemplate = filter => { `; }; -export const todoCountTemplate = length => { - return `총 ${length} 개`; -}; +export const todoCountTemplate = length => `총 ${length} 개`; diff --git a/mission001/hsna7024/package.json b/mission001/hsna7024/package.json new file mode 100644 index 0000000..8c64c0f --- /dev/null +++ b/mission001/hsna7024/package.json @@ -0,0 +1,17 @@ +{ + "name": "hsna7024", + "version": "1.0.0", + "description": "mission1", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": {}, + "devDependencies": { + "eslint": "^6.8.0", + "eslint-config-airbnb-base": "^14.0.0", + "eslint-plugin-import": "^2.20.1" + } +} From 850d85e277a9f66acdf5cd199695a13ab08b0639 Mon Sep 17 00:00:00 2001 From: Hosek Na Date: Tue, 11 Feb 2020 23:26:48 +0900 Subject: [PATCH 31/31] docs: Create .gitignore --- mission001/hsna7024/.gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 mission001/hsna7024/.gitignore diff --git a/mission001/hsna7024/.gitignore b/mission001/hsna7024/.gitignore new file mode 100644 index 0000000..d8b83df --- /dev/null +++ b/mission001/hsna7024/.gitignore @@ -0,0 +1 @@ +package-lock.json