author | Alan Dipert
<alan@dipert.org> 2021-06-02 16:07:19 UTC |
committer | Alan Dipert
<alan@dipert.org> 2021-06-02 16:07:19 UTC |
parent | d51a655bc3681ca002be2ad6c6e98ad9cccce9ad |
todo.mjs | +13 | -268 |
diff --git a/todo.mjs b/todo.mjs index 7b54ffb..6468eb6 100644 --- a/todo.mjs +++ b/todo.mjs @@ -1,15 +1,12 @@ -import { query, _, ANY } from './datalog.mjs'; -import { input, database, view } from './reactives.mjs'; -import { $el, on, entities } from './el.mjs'; +import { query, _, ANY, paths } from './datalog.mjs'; +import { input, formula, database, view } from './reactives.mjs'; +import { $el, entities } from './el.mjs'; -let todos = database([ - [0, "text", "do the thing"], - [0, "status", "ready"], - [1, "text", "do the other thing"], - [1, "status", "ready"], - [2, "text", "do that last thing"], - [2, "status", "done"] -]); +let todos = database(paths([ + {text: "do the thing", status: "ready"}, + {text: "do the other thing", status: "ready"}, + {text: "do that last thing", status: "done"} +])); let showStatus = input(ANY.VALUE); @@ -24,272 +21,20 @@ let visibleTodos = view({ let todoList = $el.ul( $el.select({ - [on.change]: ({target: {value}}) => { - showStatus.set(value === "any" ? ANY.VALUE : value) + onchange: ({target: {value}}) => { + showStatus.set(value === "any" ? ANY.VALUE : value); } }, $el.option({value: "any"}, "Any"), $el.option({value: "ready"}, "Ready"), $el.option({value: "done"}, "Done") ), - entities(visibleTodos, attrs => $el.li(attrs.text)) + entities(visibleTodos, attrs => $el.li( + formula((eid, text) => `${eid} - ${text}`)(attrs._eid, attrs.text) + )) ); document.addEventListener("DOMContentLoaded", () => { document.body.appendChild(todoList); }); -// function nextEid(db) { -// return ([...db].map(([eid]) => eid).sort((x, y) => y - x)[0] || 0) + 1; -// } -// function removeEntity(db, eid) { -// db.remove([...db].filter(([x]) => x === eid)) -// } - -// function upsert(db, eid, attrs) { -// transaction(() => { -// // TODO -// }) -// } - -// $el.ul( -// entities(todos, (attrs) => $el.li( -// $el.input({ -// type: "button", -// value: "Delete", -// [on.click]: removeEntity(todos, attr.eid.value) -// }), -// $el.span({ -// style: condp(attr.status, "done", "text-decoration: line-through"), -// [on.click]: upsert(todos, attr.eid.value, {status: statusTransition[attr.status.value]}) -// }, attr.text) -// )) -// ) - -// function todoList(todos) { -// let textInput = $el.input({type: "text"}); -// return $el.div( -// $el.form({ -// [on.submit]: e => { -// let newEid = nextEid(todos); -// todos.add([ -// [nextEid, "text", textInput.value], -// [nextEid, "status", "ready"] -// ]) -// e.preventDefault(); -// } -// }, -// textInput, -// $el.input({type: "submit", value: "Add"}), -// ), -// mapEntities( -// $el.ul(), -// todos, -// view({find: [_.eid], where: [[_.eid, "text", _._]]})(todos), -// ["text", "status"], -// ({eid, text, status}) => $el.li( -// $el.input({ -// type: "button", -// value: "x", -// [on.click]: removeEntity(todos, eid.value) -// }), -// $el.span({ -// style: formula(s => s === "done" ? "text-decoration: line-through" : "")(status), -// [on.click]: upsert(todos, eid.value, {status: status.value === "done" ? "ready" : "done"}) -// }, text) -// ) -// ) -// ); -// } - -// window.todos = todos; - -// class TodoItem { -// constructor(eid) { -// this.eid = eid; -// this.el = $el.li(document.createTextNode("")); - -// watch(([[newText]]) => { -// this.el.firstChild.textContent = newText; -// })(view({ -// find: [_.text], -// use: [_.eid], -// where: [[_.eid, "todo/text", _.text]] -// })(todos, eid)); - -// watch(([[newState]]) => { -// if (newState === "done") { -// this.el.style = "text-decoration: line-through;"; -// } else { -// this.el.style = ""; -// } -// })(view({ -// find: [_.status], -// use: [_.eid], -// where: [[_.eid, "todo/status", _.status]] -// })(todos, eid)); - -// this.el.addEventListener('click', e => { -// todos.remove([...todos].filter(([eid]) => eid === this.eid)); -// }); -// } -// destroy() { -// console.log("destroy eid", this.eid); -// // TODO -// } -// } - -// function todoList() { -// return renderChildren( -// $el.ul(), -// view({ -// find: [_.id], -// where: [[_.id, "todo/text", _._]] -// })(todos), -// TodoItem -// ); -// } - -// document.body.appendChild(todoList()) - -// let lastId = [...todos.set] -// .map(([id]) => id) -// .sort((a, b) => b - a) -// .shift(); - -// let transitions = new database([ -// ["ready", "done"], -// ["done", "ready"] -// ]); - -// function todoRemove(id) { -// todos.remove([...todos.set].filter(([eid]) => eid === id)); -// } - -// function todoAdd(text) { -// let id = ++lastId; -// todos.add([ -// [id, "todo/text", text], -// [id, "todo/status", "ready"] -// ]); -// } - -// function todoToggle(id) { -// let [[from, to]] = query({ -// find: [_.from, _.to], -// use: [[_.db1, _.db2], _.id], -// where: [ -// [_.db1, _.id, "todo/status", _.from], -// [_.db2, _.from, _.to] -// ] -// }, todos.set, transitions.set, id); -// transaction(() => { -// todos.remove([[id, "todo/status", from]]); -// todos.add([[id, "todo/status", to]]); -// }); -// } - -// let todoIds = view({ -// find: [_.id], -// where: [[_.id, _._, _._]] -// })(todos); - -// let subs = new WeakMap(); - -// function makeTodoLi(ul, id) { -// let txt = document.createTextNode(""), -// li = document.createElement("li"), -// deleteButton = document.createElement("button"), -// viewer = view({ -// find: [_.status, _.text], -// use: [_.id], -// where: [ -// [_.id, "todo/status", _.status], -// [_.id, "todo/text", _.text] -// ] -// })(todos, id), -// updater = watch((added) => { -// if (added.size()) { -// let [[status, text]] = added; -// txt.textContent = text; -// } -// })(viewer); -// li.appendChild(txt); -// li.dataset.todoId = id; -// deleteButton.innerText = "delete"; -// li.appendChild(deleteButton); -// ul.appendChild(li); -// subs.set(li, [viewer, updater]); -// } - -// function destroyTodoLi(ul, id) { -// let li = ul.querySelector(`li[data-todo-id='${id}']`) -// subs.get(li).forEach(x => x.detach()); -// ul.removeChild(li); -// } - -// document.addEventListener("DOMContentLoaded", () => { -// let ul = document.getElementById("todos-ul"); -// watch((added, removed) => { -// for (let [id] of added) makeTodoLi(ul, id); -// for (let [id] of removed) destroyTodoLi(ul, id); -// })(todoIds); -// }); -// function findTodoLi(ul, id) { -// for (let li of ul.children) { -// if (li.dataset.id == id) { -// return li; -// } -// } -// } - -// let showStatus = input(ANY.VALUE); -// // let showStatus = input("ready"); - -// let visibleTodos = view({ -// find: [_.id, _.status, _.text], -// use: [_.status], -// where: [ -// [_.id, "todo/text", _.text], -// [_.id, "todo/status", _.status] -// ] -// })(todos, showStatus); - -// let todoTexts = view({ -// find: [_.id, _.text], -// where: [[_.id, _._, _.text]] -// })(visibleTodos); - -// let todoStatuses = view({ -// find: [_.id, _.status], -// where: [[_.id, _.status, _._]] -// })(visibleTodos); - -// document.addEventListener("DOMContentLoaded", () => { -// let ul = document.getElementById("todos-ul"), -// input = document.getElementById("todos-new"), -// add = document.getElementById("todos-add"); -// add.addEventListener("click", () => { -// addTodo(input.value); -// input.value = ""; -// }); -// watch((added, removed) => { -// for (let [id, text] of added) { -// let li = findTodoLi(ul, id); -// if (!li) { -// li = document.createElement("li"); -// li.appendChild(document.createTextNode(text)); -// li.dataset.id = id; -// li.addEventListener("click", () => removeTodo(id)); -// ul.appendChild(li); -// } -// } -// for (let [id] of removed) { -// for (let child of ul.children) { -// if (child.dataset.id == id) { -// ul.removeChild(child); -// } -// } -// } -// })(todoTexts); -// });