ToDo Widget Help #4289
Replies: 6 comments 25 replies
-
Beta Was this translation helpful? Give feedback.
-
Alright, I think I got the buttons working, I still need to do a little code cleanup and still need to git rid of the dupe issue (when I f5 refresh the screen they get duped, not sure if this is a react thing where it runs twice or what, ill look into it eventually) Also still interested in any help cleaning the code up to best practices for Trilium. Here is the new code for now let TPL = `
<div>
<style>
.todoListWidget {
border: 1px solid var(--main-border-color);
min-height:6em;
resize: vertical;
width: 100%;
padding:10px;
font-family:var(--font-code);
}
.sectionTitle {
font-size: 24px;
font-weight: bold;
margin-top: 10px;
}
</style>
<span class="sectionTitle text-default">In Progress</span>
<table class="table table-hover table-sm">
<thead>
<tr>
<th></th>
<th>Title</th>
<th>Tags</th>
</tr>
</thead>
<tbody id="tbodyInProgress">
</tbody>
</table>
<span class="sectionTitle text-info">Backlog</span>
<table class="table table-hover table-sm">
<thead>
<tr>
<th></th>
<th>Title</th>
<th>Tags</th>
</tr>
</thead>
<tbody id="tbodyBacklog">
</tbody>
</table>
<span class="sectionTitle text-success">Done</span>
<table class="table table-hover table-sm">
<thead>
<tr>
<th></th>
<th>Title</th>
<th>Tags</th>
</tr>
</thead>
<tbody id="tbodyDone">
</tbody>
</table>
</div>
`
class TodoNote {
// TodoNote Template
title = "";
status = "";
tags = [];
notePath = "";
noteId = "";
}
class TodoListWidget extends api.RightPanelWidget {
todosNotes = [];
get widgetTitle() {
return "To-Do's"
}
get parentWidget() {
return "right-pane"
}
async doRenderBody() {
this.getTodos();
}
async getTodos() {
const todoNotesQuery = await api.searchForNotes("#todoItem AND note.parents.parents.title = 'To-Do' AND note.parents.title != 'Archive'");
this.todoNotes = []; // clear out array
for ( let i = 0; i < todoNotesQuery.length; i++ ) {
const note = todoNotesQuery[i];
const todoNote = new TodoNote();
todoNote.title = note.title;
todoNote.noteId = note.noteId;
todoNote.notePath = note.getBestNotePathString();
const attributes = note.getAttributes("relation", "tag");
for ( let n = 0; n < attributes.length; n++) {
const targetNote = await attributes[n].getTargetNote();
todoNote.tags.push({
title: targetNote.title,
iconClass: targetNote.getLabelValue("iconClass"),
background: targetNote.getLabelValue("badgeBackground"),
color: targetNote.getLabelValue("badgeColor")
});
}
todoNote.status = note.getParentNotes()[0].title;
this.todoNotes.push(todoNote);
}
}
async renderWidget() {
let $template = $(TPL)
for ( let tn = 0; tn < this.todoNotes.length; tn++ ) {
const todoNote = this.todoNotes[tn];
const $tr = $("<tr>");
let iconClass = "";
let clickNoteStatus = "";
switch (todoNote.status) {
case "In Progress":
iconClass = "bx-check-circle";
clickNoteStatus = "Done";
break;
case "Done":
iconClass = "bx-archive-in";
clickNoteStatus = "Archive";
break;
case "Backlog":
iconClass = "bx-send";
clickNoteStatus = "In Progress"
break;
}
let $tdButton = $("<td>");
$tdButton.append( $('<span class="button-widget icon-action bx '+iconClass+'" title="Send to '+todoNote.status+'" />')).click( async () => this.updateTask(todoNote.noteId, clickNoteStatus) );
$tr.append($tdButton);
$tr.append("<td><strong><a href='#"+todoNote.notePath+"' data-action='note' data-note-path='"+todoNote.notePath+"' class='no-tooltip-preview'>"+todoNote.title+"</a></strong></td>");
const $tagTD = $("<td>");
todoNote.tags?.forEach((tag) => {
$tagTD.append(
$("<span />").addClass("badge badge-secondary")
.text(tag.title)
.css("background", tag.background)
.css("color", tag.color)
.prepend($("<i />").addClass(tag.iconClass))
);
});
$tr.append($tagTD);
switch (todoNote.status) {
case "In Progress":
$template.find('#tbodyInProgress').append($tr);
break;
case "Backlog":
$template.find('#tbodyBacklog').append($tr);
break;
case "Done":
$template.find('#tbodyDone').append($tr);
break;
}
}
this.$body.html($template);
}
async updateTask(noteId, newStatus) {
await api.runOnBackend(
async (note_id, new_status) => {
await updateNote(note_id, new_status)
},
[noteId, newStatus]
);
this.refresh();
}
async refreshWithNote(note) {
this.refreshWidget();
}
async refreshWidget() {
await this.getTodos();
await this.renderWidget();
}
}
module.exports = new TodoListWidget() subnote "updateNote" backend script module.exports = async function (noteId, newParentTitle) {
const taskNote = await api.getNote(noteId);
// Get parent note from by using newParentTitle to search for it
const newParentNote = ( await taskNote.getParentNotes()[0].getParentNotes()[0].getChildNotes()).find((m) => m.title == newParentTitle );
// Bascially move note to newParentNote
const oldParentNoteId = taskNote.getParentNotes()[0].noteId;
await api.toggleNoteInParent(true, taskNote.noteId, newParentNote.noteId);
await api.toggleNoteInParent(false, taskNote.noteId,oldParentNoteId );
}; |
Beta Was this translation helpful? Give feedback.
-
Added a new task button to the top of the widget module.exports = async function(mainTodoNoteName, newParentTitle) {
const taskNoteId = await api.runOnBackend((main_todo_note_name, new_parent_title) => {
const parentNoteQuery = api.searchForNote("note.title = '" + new_parent_title + "' AND note.parents.title = '" + main_todo_note_name + "'");
const resp = api.createTextNote(parentNoteQuery.noteId, "New Task", '');
return resp.note.noteId;
}, [mainTodoNoteName, newParentTitle]);
await api.waitUntilSynced();
await api.activateNewNote(taskNoteId);
}; <div class="header-actions">
<span
id="newTask"
class="button-widget icon-action bx bx-list-plus"
title="New Todo" />
</div> added this to the render method $template.find('#newTask').click(async () => createNewNote(this.MAIN_NOTE_NAME, this.NEW_NOTE_PARENT_NAME)); |
Beta Was this translation helpful? Give feedback.
-
Does anyone know how I can get a api.addButtonToToolbar({
title: 'Hide To-Do\'s',
icon: 'bx bx-show',
action: () => {
}
}); to basically show or hide my widget? |
Beta Was this translation helpful? Give feedback.
-
Added some Tabs and the ability to have multiple Todo lists. I have a refresh button and a new task button now also. |
Beta Was this translation helpful? Give feedback.
-
Thank you, this is exactly what i was looking for to help me stay on task at work. Is there an easy way to get the active To Do list (tab) to be a different color? if i have multiple to do list i would like to have the one that is active visually identified to make sure i can add an item to the correct list. |
Beta Was this translation helpful? Give feedback.
-
I've been digging through the API docs along with other widget code to try and put this together.
I want a widget to track and update my todo list.
I am using this plugin #2946
I created this widget
What I am looking for is the following help:
I'll keep playing with it but would not mind help/opinions.
Beta Was this translation helpful? Give feedback.
All reactions