Skip to content

Commit

Permalink
allow to filter by tags
Browse files Browse the repository at this point in the history
  • Loading branch information
falk-werner committed Jan 21, 2024
1 parent ba0dbf3 commit f5efafd
Show file tree
Hide file tree
Showing 7 changed files with 175 additions and 17 deletions.
6 changes: 3 additions & 3 deletions frontend/fakenoteprovider.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ class Note {
content;
tags;

constructor(name, content) {
constructor(name, content, tags) {
this.name = name;
this.content = content || "";
this.tags = [];
this.tags = tags || [];
}
}

Expand All @@ -19,7 +19,7 @@ class FakeNoteProvider extends NoteProvider {
constructor() {
super();
this.#notes = new Map([
["Sample", new Note("Sample", "# Sample Note\n")]
["Sample", new Note("Sample", "# Sample Note\n", ["Sample"])]
]);
}

Expand Down
7 changes: 6 additions & 1 deletion frontend/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { init_settings } from "./settings.js"
import { FakeNoteProvider } from "./fakenoteprovider.js"
import { NoteList } from "./notelist.js"
import { Editor } from "./editor.js"
import { TagList } from "./taglist.js"

init_titlebar();
init_settings();
Expand All @@ -15,9 +16,13 @@ slider_attach(document.querySelector("#slider"));
const editor = new Editor();

const noteProvider = new FakeNoteProvider();

const taglist_elemnt = document.querySelector("#taglist");
const taglist = new TagList(taglist_elemnt, noteProvider);

const notelist_element = document.querySelector("#notelist");
const filter_element = document.querySelector('#filter');
const notelist = new NoteList(noteProvider, notelist_element, filter_element, editor);
const notelist = new NoteList(noteProvider, notelist_element, filter_element, taglist, editor);
document.querySelector("#add-note").addEventListener("click", async () => {
notelist.add_new();
})
Expand Down
50 changes: 43 additions & 7 deletions frontend/note.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,34 @@

function arrays_equals(a, b) {
if (a.length != b.length) {
return false;
}

for(const item of a) {
if (!b.includes(a)) {
return false;
}
}

return true;
}

class Note {
#name;
#content;
#tags;
#provider;
#taglist;
#editor;
#list_item;
#notelist
#notelist;

constructor(name, content, tags, provider, notelist, editor) {
constructor(name, content, tags, provider, notelist, taglist, editor) {
this.#name = name;
this.#content = content;
this.#tags = tags;
this.#provider = provider;
this.#taglist = taglist;
this.#editor = editor;
this.#notelist = notelist;
this.#create_listentry();
Expand Down Expand Up @@ -60,11 +77,14 @@ class Note {

if (content != this.#content) {
this.#content = content;
this.#provider.write(this.#name, content);
await this.#provider.write(this.#name, content);
}

this.#tags = tags;
this.#provider.write_tags(this.#name, tags);
if (!arrays_equals(this.#tags, tags)) {
this.#tags = tags;
await this.#provider.write_tags(this.#name, tags);
this.#taglist.update();
}
}

async remove() {
Expand All @@ -74,10 +94,26 @@ class Note {
this.#notelist.remove(this);
}

applyFilter(filter) {
#filter_by_tags(tags) {
if (tags.length == 0) {
return true;
}

for(let tag of this.#tags) {
tag = tag.toLowerCase();
if (tags.includes(tag)) {
return true;
}
}

return false;
}

apply_filter(filter, tags) {
const name = this.#name.toLowerCase();
const content = this.#content.toLowerCase();
if ((name.includes(filter)) || (content.includes(filter))) {
if ( (this.#filter_by_tags(tags)) &&
((name.includes(filter)) || (content.includes(filter))) ) {
this.#list_item.classList.remove('hidden');
}
else {
Expand Down
15 changes: 10 additions & 5 deletions frontend/notelist.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,21 @@ class NoteList {
#provider
#element;
#filter;
#taglist;
#editor;
#notes;
#active_note;

constructor(provider, element, filter, editor) {
constructor(provider, element, filter, taglist, editor) {
this.#provider = provider;
this.#element = element;
this.#filter = filter;
this.#taglist = taglist;
this.#editor = editor;
this.#active_note = null;

this.#filter.addEventListener('input', () => this.applyFilter());
this.#filter.addEventListener('input', () => this.apply_filter());
this.#taglist.change_handler = () => { this.apply_filter() };
this.#update();
}

Expand All @@ -33,7 +36,7 @@ class NoteList {
async #add(name, activate) {
const content = await this.#provider.read(name);
const tags = await this.#provider.read_tags(name);
const note = new Note(name, content, tags, this.#provider, this, this.#editor);
const note = new Note(name, content, tags, this.#provider, this, this.#taglist, this.#editor);
this.#notes.set(name, note);
if ((!this.#active_note) || (activate)) {
this.activate(note);
Expand Down Expand Up @@ -75,10 +78,12 @@ class NoteList {
}
}

applyFilter() {
apply_filter() {
const filter = this.#filter.value.toLowerCase();
const tags = this.#taglist.active_tags;

for(const note of this.#notes.values()) {
note.applyFilter(filter);
note.apply_filter(filter, tags);
}
}
}
Expand Down
24 changes: 24 additions & 0 deletions frontend/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -147,4 +147,28 @@ dialog .controls {
display: flex;
flex-direction: row;
justify-content: flex-end;
}

#taglist {
display: flex;
flex-direction: row;
flex-wrap: wrap;
margin: 5px;
gap: 5px;
}

#taglist > div {
flex: none;
display: inline-block;
text-decoration: none;
color: inherit;
background-color: #d0d0d0;
border-radius: 10px;
padding-left: 5px;
padding-right: 5px;
cursor: pointer;
}

#taglist > div.active {
background-color: #b0d0f0;
}
87 changes: 87 additions & 0 deletions frontend/taglist.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@

class TagList {

#element
#provider
#tags
#change_handler

constructor(element, provider) {
this.#element = element;
this.#provider = provider;
this.#tags = new Map();
this.#change_handler = null;

this.update();
}

get active_tags() {
const result = [];
for(const [name, active] of this.#tags.entries()) {
if (active) {
result.push(name);
}
}
return result;
}

set change_handler(new_handler) {
this.#change_handler = new_handler;
}

async update() {
const new_tags = new Map();
const notes = await this.#provider.list();
for(const note of notes) {
const tags = await this.#provider.read_tags(note);
for(let tag of tags) {
tag = tag.toLowerCase();
if (!new_tags.has(tag)) {
const active = this.#tags.has(tag) ? this.#tags.get(tag) : false;
new_tags.set(tag, active);
}
}
}
this.#tags = new_tags;

this.#element.innerHTML = "";
const tags = [...this.#tags.entries()].sort();
for(const [name, active] of tags) {
const item = document.createElement("div");
this.#element.appendChild(item);
item.textContent = name;
if (active) {
item.classList.add("active");
}
item.addEventListener("click", () => {
this.toggle(item, name);
},false);
}

this.#fire();
}

toggle(item, tag) {
if (this.#tags.has(tag)) {
const active = !this.#tags.get(tag);
this.#tags.set(tag, active);

if (active) {
item.classList.add("active");
}
else {
item.classList.remove("active");
}
}

this.#fire();
}

#fire() {
if (this.#change_handler) {
this.#change_handler();
}
}
}

export { TagList }
3 changes: 2 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,9 @@
<div id="main" class="wrapper">
<div id="sidebar">
<div class="controls">
<input id="filter" type="text" value="" />
<input id="filter" type="text" value="" />
</div>
<div id="taglist"></div>
<hr />
<ul id="notelist"></ul>
</div>
Expand Down

0 comments on commit f5efafd

Please sign in to comment.