Implement basic notes store and listing notes from it

This commit is contained in:
Adrian Gruntkowski 2024-11-12 16:25:56 +01:00
parent 935061e73b
commit 5706314451
5 changed files with 160 additions and 4 deletions

View file

@ -37,7 +37,9 @@
<div class="note">
<task-list>
<ul>
<li draggable="true"><task-list-item checked>one</task-list-item></li>
<li draggable="true">
<task-list-item checked>one</task-list-item>
</li>
<li draggable="true"><task-list-item>two</task-list-item></li>
<li draggable="true"><task-list-item>three</task-list-item></li>
<li draggable="true"><task-list-item>four</task-list-item></li>
@ -50,6 +52,8 @@
</ul>
</task-list>
</div>
<div id="notes"></div>
</div>
<template id="task-list-item">

View file

@ -83,13 +83,13 @@ class EditableArea extends HTMLElement {
}
#sync() {
this.displayElement.innerHTML = render(this.inputElement.value);
this.displayElement.innerHTML = renderText(this.inputElement.value);
this.inputElement.style.height = this.displayElement.scrollHeight + "px";
this.inputElement.style.width = this.displayElement.scrollWidth + "px";
}
}
function render(text) {
export function renderText(text) {
return text.replace(/(?:\r\n|\r|\n)/g, "<br>") + "<br>";
}

View file

@ -1 +1,58 @@
import "./components.js";
import { renderText } from "./components.js";
import { NoteStore } from "./store.js";
const Notes = new NoteStore("jenot-app");
Notes.addEventListener("save", render.bind(this));
Notes.reset();
Notes.add({
type: "note",
content: "This is a test note",
});
Notes.add({
type: "tasklist",
content: [
{ checked: false, content: "First item" },
{ checked: true, content: "Second item" },
{ checked: false, content: "Third item" },
],
});
Notes.saveStorage();
function render() {
const notes = Notes.all();
const notesContainer = document.querySelector("#notes");
notesContainer.textContent = "";
notes.forEach((note) => {
const container = document.createElement("div");
container.id = note.id;
container.classList.add("note");
container.classList.add("readonly");
if (note.type === "note") {
container.innerHTML = renderText(note.content);
} else if (note.type === "tasklist") {
const list = document.createElement("ul");
note.content.forEach((task) => {
const item = document.createElement("li");
const check = document.createElement("p");
check.textContent = task.checked ? "☑" : "☐";
item.appendChild(check);
const itemContent = document.createElement("p");
itemContent.innerHTML = renderText(task.content);
item.appendChild(itemContent);
list.append(item);
});
container.appendChild(list);
}
notesContainer.appendChild(container);
});
}

81
js/store.js Normal file
View file

@ -0,0 +1,81 @@
export class NoteStore extends EventTarget {
localStorageKey;
notes = [];
editedNoteId = "none";
/*
Note structure:
- id - unique note ID
- type - either `note` or `tasklist`
- content - note's content
- created - timestamp
*/
constructor(localStorageKey) {
super();
this.localStorageKey = localStorageKey;
this.#readStorage();
// handle notes edited in another window
window.addEventListener(
"storage",
() => {
this.#readStorage();
this.saveStorage();
},
false,
);
}
all = () => this.notes;
get = () => this.notes.find((note) => note.id === id);
getEditedNoteId = () => this.editedNoteId;
add(note) {
this.notes.unshift({
id: "id_" + Date.now(),
type: note.type,
content: note.content,
created: new Date(),
});
}
reset() {
this.notes = [];
}
remove({ id }) {
this.notes = this.notes.filter((note) => note.id !== id);
}
update(note) {
this.notes = this.notes.map((n) => (n.id === note.id ? note : n));
}
setEditedNoteId(id) {
this.editedNoteId = id;
}
saveStorage() {
window.localStorage.setItem(
this.localStorageKey + "_notes",
JSON.stringify(this.notes),
);
window.localStorage.setItem(
this.localStorageKey + "_editedNoteId",
this.editedNoteId,
);
this.dispatchEvent(new CustomEvent("save"));
}
#readStorage() {
this.notes = JSON.parse(
window.localStorage.getItem(this.localStorageKey + "_notes") || "[]",
);
this.editedNoteId =
window.localStorage.getItem(this.localStorageKey + "_editedNoteId") ||
"none";
}
}

View file

@ -167,3 +167,17 @@ div#content {
padding: 4px 8px;
margin-bottom: 20px;
}
.note.readonly ul {
wdith: 100%;
list-style-type: none;
margin: 0;
padding: 0;
}
.note.readonly ul li {
display: flex;
gap: 6px;
align-items: baseline;
margin-bottom: 4px;
}