Skip to content

Commit

Permalink
implement kanban board
Browse files Browse the repository at this point in the history
  • Loading branch information
Cyril Leblanc committed Nov 29, 2023
1 parent 2aab3cd commit 1fb31f0
Show file tree
Hide file tree
Showing 11 changed files with 141 additions and 0 deletions.
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,30 @@
# trilium-kanban
A Kanban integration for Trilium Notes

![Demo](screenshots/demo.gif)

## Installation

1. Download the latest release from the [releases page](https://github.com/CyrilLeblanc/trilium-kanban/releases)
2. Import the `.zip` file into Trilium for right-clicking on a note and selecting `Import into note`.
3. Setup a Kanban board. See [Usage](#usage) for more details.

## Features

- Kanban view for child notes.
- Drag and drop to change the order of items.
- Drag and drop to change the board of an item.
- Drag and drop to change the order of boards.
- Click on an item to open the note.

## Create a Kanban board

- Create a note of type `Render Note`.
- Add the relation to `kanban` HTML note.
- Add the label `#sortOrder=sortOrder`.
- Create a board by creating a sub-note.
- Create an item by creating a sub-note of a board.

## Credits
- [Trilium Notes](https://github.com/zadam/trilium)
- [jKanban](https://github.com/riktar/jkanban)
Binary file added screenshots/demo.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file added src/kanban.html
Empty file.
1 change: 1 addition & 0 deletions src/kanban/jkanban.min.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions src/kanban/js.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// the only custom change made in "jkanban.min.js" is the
// use of "globalThis.jKanban" instead of "this.jKanban"
// this is made to prevent an error in the loading of the library

const kanban = new jKanban({
element: "#kanban",
boards: await getInitialData(),
dropEl: moveItemToBoard,
click: showNote,
dragendBoard: reorderBoards
})
23 changes: 23 additions & 0 deletions src/kanban/js/getInitialValue.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
module.exports = async function() {
const { noteId } = api.originEntity;

return await api.runOnBackend(kanbanNoteId => {
const kanbanNote = api.getNote(kanbanNoteId);
const boards = kanbanNote.getChildNotes();

return boards.map(board => {
const items = board.getChildNotes();

return {
id: board.noteId,
title: board.title,
item: items.map(item => (
{
id: item.noteId,
title: item.title
}
))
};
});
}, [noteId]);
}
1 change: 1 addition & 0 deletions src/kanban/js/jkanban.min.js

Large diffs are not rendered by default.

27 changes: 27 additions & 0 deletions src/kanban/js/moveItemToBoard.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
module.exports = async function(el, target, source, sibling) {
if (target == source) {
return;
}

const itemId = $(el).data("eid");
const targetBoardId = $(target).parents(".kanban-board").data("id");
const sourceBoardId = $(source).parents(".kanban-board").data("id");

const result = await api.runOnBackend((itemId, targetBoardId, sourceBoardId) => {
if (targetBoardId != sourceBoardId) {
// add in target board
api.toggleNoteInParent(true, itemId, targetBoardId);

// remove item from source board
api.toggleNoteInParent(false, itemId, sourceBoardId);
}

return true;
}, [itemId, targetBoardId, sourceBoardId])

if (!result) {
api.showError("An error occurred while moving the item.");
}

await api.waitUntilSynced();
};
38 changes: 38 additions & 0 deletions src/kanban/js/reorderBoards.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
module.exports = async function(el) {
const { noteId: kanbanNoteId } = api.originEntity;

// get notes id ordered
const $container = $(el).parents(".kanban-container");
const noteOrderedIds = [];
$container.children().each((index, el) => {
const id = $(el).data("id");
noteOrderedIds.push(id);
});

const result = await api.runOnBackend((kanbanNoteId, noteOrderedIds) => {
const kanbanNote = api.getNote(kanbanNoteId);
const orderLabel = kanbanNote.getLabelValue("sorted");

// don't reorder if there's no #sorted attribute on kanban note
if (!orderLabel) {
return true;
}

noteOrderedIds.forEach((noteId, index) => {
const note = api.getNote(noteId);

if (note.getLabelValue(orderLabel) != index) {
note.setLabel(orderLabel, index);
note.save();
}
});

return true;
}, [kanbanNoteId, noteOrderedIds]);

if (!result) {
api.showError("An error occured when ordering boards.");
}

await api.waitUntilSynced();
}
5 changes: 5 additions & 0 deletions src/kanban/js/showNote.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = function (el) {
const noteId = $(el).data("eid");

api.activateNote(noteId);
}
7 changes: 7 additions & 0 deletions src/kanban/kanban.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.kanban-board {
background-color: var(--left-pane-background-color);
}

.kanban-item {
background-color: var(--main-background-color);
}

0 comments on commit 1fb31f0

Please sign in to comment.