mirror of
https://github.com/zadam/trilium.git
synced 2025-10-09 15:08:14 +08:00
feat(views/board): set up reordering for same column
This commit is contained in:
parent
a428ea7beb
commit
08d60c554c
1 changed files with 66 additions and 23 deletions
|
@ -2,6 +2,7 @@ import { setupHorizontalScrollViaWheel } from "../../widget_utils";
|
||||||
import ViewMode, { ViewModeArgs } from "../view_mode";
|
import ViewMode, { ViewModeArgs } from "../view_mode";
|
||||||
import { getBoardData } from "./data";
|
import { getBoardData } from "./data";
|
||||||
import attributeService from "../../../services/attributes";
|
import attributeService from "../../../services/attributes";
|
||||||
|
import branchService from "../../../services/branches";
|
||||||
import { EventData } from "../../../components/app_context";
|
import { EventData } from "../../../components/app_context";
|
||||||
|
|
||||||
const TPL = /*html*/`
|
const TPL = /*html*/`
|
||||||
|
@ -100,6 +101,7 @@ export default class BoardView extends ViewMode<StateInfo> {
|
||||||
private $root: JQuery<HTMLElement>;
|
private $root: JQuery<HTMLElement>;
|
||||||
private $container: JQuery<HTMLElement>;
|
private $container: JQuery<HTMLElement>;
|
||||||
private draggedNote: any = null;
|
private draggedNote: any = null;
|
||||||
|
private draggedBranch: any = null;
|
||||||
private draggedNoteElement: JQuery<HTMLElement> | null = null;
|
private draggedNoteElement: JQuery<HTMLElement> | null = null;
|
||||||
|
|
||||||
constructor(args: ViewModeArgs) {
|
constructor(args: ViewModeArgs) {
|
||||||
|
@ -147,6 +149,7 @@ export default class BoardView extends ViewMode<StateInfo> {
|
||||||
|
|
||||||
for (const item of columnItems) {
|
for (const item of columnItems) {
|
||||||
const note = item.note;
|
const note = item.note;
|
||||||
|
const branch = item.branch;
|
||||||
if (!note) {
|
if (!note) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -158,13 +161,14 @@ export default class BoardView extends ViewMode<StateInfo> {
|
||||||
const $noteEl = $("<div>")
|
const $noteEl = $("<div>")
|
||||||
.addClass("board-note")
|
.addClass("board-note")
|
||||||
.attr("data-note-id", note.noteId)
|
.attr("data-note-id", note.noteId)
|
||||||
|
.attr("data-branch-id", branch.branchId)
|
||||||
.attr("data-current-column", column)
|
.attr("data-current-column", column)
|
||||||
.text(note.title);
|
.text(note.title);
|
||||||
|
|
||||||
$noteEl.prepend($iconEl);
|
$noteEl.prepend($iconEl);
|
||||||
|
|
||||||
// Setup drag functionality for the note
|
// Setup drag functionality for the note
|
||||||
this.setupNoteDrag($noteEl, note);
|
this.setupNoteDrag($noteEl, note, branch);
|
||||||
|
|
||||||
$columnEl.append($noteEl);
|
$columnEl.append($noteEl);
|
||||||
}
|
}
|
||||||
|
@ -173,11 +177,12 @@ export default class BoardView extends ViewMode<StateInfo> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private setupNoteDrag($noteEl: JQuery<HTMLElement>, note: any) {
|
private setupNoteDrag($noteEl: JQuery<HTMLElement>, note: any, branch: any) {
|
||||||
$noteEl.attr("draggable", "true");
|
$noteEl.attr("draggable", "true");
|
||||||
|
|
||||||
$noteEl.on("dragstart", (e) => {
|
$noteEl.on("dragstart", (e) => {
|
||||||
this.draggedNote = note;
|
this.draggedNote = note;
|
||||||
|
this.draggedBranch = branch;
|
||||||
this.draggedNoteElement = $noteEl;
|
this.draggedNoteElement = $noteEl;
|
||||||
$noteEl.addClass("dragging");
|
$noteEl.addClass("dragging");
|
||||||
|
|
||||||
|
@ -192,6 +197,7 @@ export default class BoardView extends ViewMode<StateInfo> {
|
||||||
$noteEl.on("dragend", () => {
|
$noteEl.on("dragend", () => {
|
||||||
$noteEl.removeClass("dragging");
|
$noteEl.removeClass("dragging");
|
||||||
this.draggedNote = null;
|
this.draggedNote = null;
|
||||||
|
this.draggedBranch = null;
|
||||||
this.draggedNoteElement = null;
|
this.draggedNoteElement = null;
|
||||||
|
|
||||||
// Remove all drop indicators
|
// Remove all drop indicators
|
||||||
|
@ -229,34 +235,65 @@ export default class BoardView extends ViewMode<StateInfo> {
|
||||||
$columnEl.on("drop", async (e) => {
|
$columnEl.on("drop", async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
$columnEl.removeClass("drag-over");
|
$columnEl.removeClass("drag-over");
|
||||||
$columnEl.find(".board-drop-indicator").removeClass("show");
|
|
||||||
|
|
||||||
if (this.draggedNote && this.draggedNoteElement) {
|
if (this.draggedNote && this.draggedNoteElement && this.draggedBranch) {
|
||||||
const currentColumn = this.draggedNoteElement.attr("data-current-column");
|
const currentColumn = this.draggedNoteElement.attr("data-current-column");
|
||||||
|
|
||||||
if (currentColumn !== column) {
|
// Capture drop indicator position BEFORE removing it
|
||||||
try {
|
const dropIndicator = $columnEl.find(".board-drop-indicator.show");
|
||||||
// Update the note's status label
|
let targetBranchId: string | null = null;
|
||||||
await attributeService.setLabel(this.draggedNote.noteId, "status", column);
|
let moveType: "before" | "after" | null = null;
|
||||||
|
|
||||||
// Move the note element to the new column
|
if (dropIndicator.length > 0) {
|
||||||
const dropIndicator = $columnEl.find(".board-drop-indicator.show");
|
// Find the note element that the drop indicator is positioned relative to
|
||||||
if (dropIndicator.length > 0) {
|
const nextNote = dropIndicator.next(".board-note");
|
||||||
dropIndicator.after(this.draggedNoteElement);
|
const prevNote = dropIndicator.prev(".board-note");
|
||||||
} else {
|
|
||||||
$columnEl.append(this.draggedNoteElement);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the data attribute
|
if (nextNote.length > 0) {
|
||||||
this.draggedNoteElement.attr("data-current-column", column);
|
targetBranchId = nextNote.attr("data-branch-id") || null;
|
||||||
|
moveType = "before";
|
||||||
// Show success feedback (optional)
|
} else if (prevNote.length > 0) {
|
||||||
console.log(`Moved note "${this.draggedNote.title}" from "${currentColumn}" to "${column}"`);
|
targetBranchId = prevNote.attr("data-branch-id") || null;
|
||||||
} catch (error) {
|
moveType = "after";
|
||||||
console.error("Failed to update note status:", error);
|
|
||||||
// Optionally show user-facing error message
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Now remove the drop indicator
|
||||||
|
$columnEl.find(".board-drop-indicator").removeClass("show");
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Handle column change
|
||||||
|
if (currentColumn !== column) {
|
||||||
|
await attributeService.setLabel(this.draggedNote.noteId, "status", column);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle position change (works for both same column and different column moves)
|
||||||
|
if (targetBranchId && moveType) {
|
||||||
|
if (moveType === "before") {
|
||||||
|
console.log("Move before branch:", this.draggedBranch.branchId, "to", targetBranchId);
|
||||||
|
await branchService.moveBeforeBranch([this.draggedBranch.branchId], targetBranchId);
|
||||||
|
} else if (moveType === "after") {
|
||||||
|
console.log("Move after branch:", this.draggedBranch.branchId, "to", targetBranchId);
|
||||||
|
await branchService.moveAfterBranch([this.draggedBranch.branchId], targetBranchId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the UI
|
||||||
|
if (dropIndicator.length > 0) {
|
||||||
|
dropIndicator.after(this.draggedNoteElement);
|
||||||
|
} else {
|
||||||
|
$columnEl.append(this.draggedNoteElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the data attributes
|
||||||
|
this.draggedNoteElement.attr("data-current-column", column);
|
||||||
|
|
||||||
|
// Show success feedback
|
||||||
|
console.log(`Moved note "${this.draggedNote.title}" from "${currentColumn}" to "${column}"`);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to update note position:", error);
|
||||||
|
// Optionally show user-facing error message
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -302,10 +339,16 @@ export default class BoardView extends ViewMode<StateInfo> {
|
||||||
}
|
}
|
||||||
|
|
||||||
async onEntitiesReloaded({ loadResults }: EventData<"entitiesReloaded">) {
|
async onEntitiesReloaded({ loadResults }: EventData<"entitiesReloaded">) {
|
||||||
|
// React to changes in "status" attribute for notes in this board
|
||||||
if (loadResults.getAttributeRows().some(attr => attr.name === "status" && this.noteIds.includes(attr.noteId!))) {
|
if (loadResults.getAttributeRows().some(attr => attr.name === "status" && this.noteIds.includes(attr.noteId!))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// React to changes in branches for subchildren (e.g., moved, added, or removed notes)
|
||||||
|
if (loadResults.getBranchRows().some(branch => this.noteIds.includes(branch.noteId!))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue