From 4826898c553eb87e020f341395b25ee537be1fa9 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Mon, 21 Jul 2025 11:01:42 +0300 Subject: [PATCH] refactor(views/board): move drag logic to separate file --- .../view_widgets/board_view/drag_handler.ts | 318 ++++++++++++++ .../widgets/view_widgets/board_view/index.ts | 390 +----------------- 2 files changed, 335 insertions(+), 373 deletions(-) create mode 100644 apps/client/src/widgets/view_widgets/board_view/drag_handler.ts diff --git a/apps/client/src/widgets/view_widgets/board_view/drag_handler.ts b/apps/client/src/widgets/view_widgets/board_view/drag_handler.ts new file mode 100644 index 000000000..a11970491 --- /dev/null +++ b/apps/client/src/widgets/view_widgets/board_view/drag_handler.ts @@ -0,0 +1,318 @@ +import branchService from "../../../services/branches"; +import BoardApi from "./api"; + +export interface DragContext { + draggedNote: any; + draggedBranch: any; + draggedNoteElement: JQuery | null; +} + +export class BoardDragHandler { + private $container: JQuery; + private api: BoardApi; + private context: DragContext; + private onBoardRefresh: () => Promise; + + constructor( + $container: JQuery, + api: BoardApi, + context: DragContext, + onBoardRefresh: () => Promise + ) { + this.$container = $container; + this.api = api; + this.context = context; + this.onBoardRefresh = onBoardRefresh; + } + + setupNoteDrag($noteEl: JQuery, note: any, branch: any) { + $noteEl.attr("draggable", "true"); + + // Mouse drag events + this.setupMouseDrag($noteEl, note, branch); + + // Touch drag events + this.setupTouchDrag($noteEl, note, branch); + } + + private setupMouseDrag($noteEl: JQuery, note: any, branch: any) { + $noteEl.on("dragstart", (e) => { + this.context.draggedNote = note; + this.context.draggedBranch = branch; + this.context.draggedNoteElement = $noteEl; + $noteEl.addClass("dragging"); + + // Set drag data + const originalEvent = e.originalEvent as DragEvent; + if (originalEvent.dataTransfer) { + originalEvent.dataTransfer.effectAllowed = "move"; + originalEvent.dataTransfer.setData("text/plain", note.noteId); + } + }); + + $noteEl.on("dragend", () => { + $noteEl.removeClass("dragging"); + this.context.draggedNote = null; + this.context.draggedBranch = null; + this.context.draggedNoteElement = null; + + // Remove all drop indicators + this.$container.find(".board-drop-indicator").removeClass("show"); + }); + } + + private setupTouchDrag($noteEl: JQuery, note: any, branch: any) { + let isDragging = false; + let startY = 0; + let startX = 0; + let dragThreshold = 10; // Minimum distance to start dragging + let $dragPreview: JQuery | null = null; + + $noteEl.on("touchstart", (e) => { + const touch = (e.originalEvent as TouchEvent).touches[0]; + startX = touch.clientX; + startY = touch.clientY; + isDragging = false; + $dragPreview = null; + }); + + $noteEl.on("touchmove", (e) => { + e.preventDefault(); // Prevent scrolling + const touch = (e.originalEvent as TouchEvent).touches[0]; + const deltaX = Math.abs(touch.clientX - startX); + const deltaY = Math.abs(touch.clientY - startY); + + // Start dragging if we've moved beyond threshold + if (!isDragging && (deltaX > dragThreshold || deltaY > dragThreshold)) { + isDragging = true; + this.context.draggedNote = note; + this.context.draggedBranch = branch; + this.context.draggedNoteElement = $noteEl; + $noteEl.addClass("dragging"); + + // Create drag preview + $dragPreview = this.createDragPreview($noteEl, touch.clientX, touch.clientY); + } + + if (isDragging && $dragPreview) { + // Update drag preview position + $dragPreview.css({ + left: touch.clientX - ($dragPreview.outerWidth() || 0) / 2, + top: touch.clientY - ($dragPreview.outerHeight() || 0) / 2 + }); + + // Find element under touch point + const elementBelow = document.elementFromPoint(touch.clientX, touch.clientY); + if (elementBelow) { + const $columnEl = $(elementBelow).closest('.board-column'); + + if ($columnEl.length > 0) { + // Remove drag-over from all columns + this.$container.find('.board-column').removeClass('drag-over'); + $columnEl.addClass('drag-over'); + + // Show drop indicator + this.showDropIndicatorAtPoint($columnEl, touch.clientY); + } else { + // Remove all drag indicators if not over a column + this.$container.find('.board-column').removeClass('drag-over'); + this.$container.find(".board-drop-indicator").removeClass("show"); + } + } + } + }); + + $noteEl.on("touchend", async (e) => { + if (isDragging) { + const touch = (e.originalEvent as TouchEvent).changedTouches[0]; + const elementBelow = document.elementFromPoint(touch.clientX, touch.clientY); + if (elementBelow) { + const $columnEl = $(elementBelow).closest('.board-column'); + + if ($columnEl.length > 0) { + const column = $columnEl.attr('data-column'); + if (column && this.context.draggedNote && this.context.draggedNoteElement && this.context.draggedBranch) { + await this.handleNoteDrop($columnEl, column); + } + } + } + + // Clean up + $noteEl.removeClass("dragging"); + this.context.draggedNote = null; + this.context.draggedBranch = null; + this.context.draggedNoteElement = null; + this.$container.find('.board-column').removeClass('drag-over'); + this.$container.find(".board-drop-indicator").removeClass("show"); + + // Remove drag preview + if ($dragPreview) { + $dragPreview.remove(); + $dragPreview = null; + } + } + isDragging = false; + }); + } + + setupColumnDropZone($columnEl: JQuery, column: string) { + $columnEl.on("dragover", (e) => { + e.preventDefault(); + const originalEvent = e.originalEvent as DragEvent; + if (originalEvent.dataTransfer) { + originalEvent.dataTransfer.dropEffect = "move"; + } + + if (this.context.draggedNote) { + $columnEl.addClass("drag-over"); + this.showDropIndicator($columnEl, e); + } + }); + + $columnEl.on("dragleave", (e) => { + // Only remove drag-over if we're leaving the column entirely + const rect = $columnEl[0].getBoundingClientRect(); + const originalEvent = e.originalEvent as DragEvent; + const x = originalEvent.clientX; + const y = originalEvent.clientY; + + if (x < rect.left || x > rect.right || y < rect.top || y > rect.bottom) { + $columnEl.removeClass("drag-over"); + $columnEl.find(".board-drop-indicator").removeClass("show"); + } + }); + + $columnEl.on("drop", async (e) => { + e.preventDefault(); + $columnEl.removeClass("drag-over"); + + if (this.context.draggedNote && this.context.draggedNoteElement && this.context.draggedBranch) { + await this.handleNoteDrop($columnEl, column); + } + }); + } + + private createDragPreview($noteEl: JQuery, x: number, y: number): JQuery { + // Clone the note element for the preview + const $preview = $noteEl.clone(); + + $preview + .addClass('board-drag-preview') + .css({ + position: 'fixed', + left: x - ($noteEl.outerWidth() || 0) / 2, + top: y - ($noteEl.outerHeight() || 0) / 2, + pointerEvents: 'none', + zIndex: 10000 + }) + .appendTo('body'); + + return $preview; + } + + private showDropIndicator($columnEl: JQuery, e: JQuery.DragOverEvent) { + const originalEvent = e.originalEvent as DragEvent; + const mouseY = originalEvent.clientY; + this.showDropIndicatorAtY($columnEl, mouseY); + } + + private showDropIndicatorAtPoint($columnEl: JQuery, touchY: number) { + this.showDropIndicatorAtY($columnEl, touchY); + } + + private showDropIndicatorAtY($columnEl: JQuery, y: number) { + const columnRect = $columnEl[0].getBoundingClientRect(); + const relativeY = y - columnRect.top; + + // Find existing drop indicator or create one + let $dropIndicator = $columnEl.find(".board-drop-indicator"); + if ($dropIndicator.length === 0) { + $dropIndicator = $("
").addClass("board-drop-indicator"); + $columnEl.append($dropIndicator); + } + + // Find the best position to insert the note + const $notes = this.context.draggedNoteElement ? + $columnEl.find(".board-note").not(this.context.draggedNoteElement) : + $columnEl.find(".board-note"); + let insertAfterElement: HTMLElement | null = null; + + $notes.each((_, noteEl) => { + const noteRect = noteEl.getBoundingClientRect(); + const noteMiddle = noteRect.top + noteRect.height / 2 - columnRect.top; + + if (relativeY > noteMiddle) { + insertAfterElement = noteEl; + } + }); + + // Position the drop indicator + if (insertAfterElement) { + $(insertAfterElement).after($dropIndicator); + } else { + // Insert at the beginning (after the header) + const $header = $columnEl.find("h3"); + $header.after($dropIndicator); + } + + $dropIndicator.addClass("show"); + } + + private async handleNoteDrop($columnEl: JQuery, column: string) { + const draggedNoteElement = this.context.draggedNoteElement; + const draggedNote = this.context.draggedNote; + const draggedBranch = this.context.draggedBranch; + + if (draggedNote && draggedNoteElement && draggedBranch) { + const currentColumn = draggedNoteElement.attr("data-current-column"); + + // Capture drop indicator position BEFORE removing it + const dropIndicator = $columnEl.find(".board-drop-indicator.show"); + let targetBranchId: string | null = null; + let moveType: "before" | "after" | null = null; + + if (dropIndicator.length > 0) { + // Find the note element that the drop indicator is positioned relative to + const nextNote = dropIndicator.next(".board-note"); + const prevNote = dropIndicator.prev(".board-note"); + + if (nextNote.length > 0) { + targetBranchId = nextNote.attr("data-branch-id") || null; + moveType = "before"; + } else if (prevNote.length > 0) { + targetBranchId = prevNote.attr("data-branch-id") || null; + moveType = "after"; + } + } + + try { + // Handle column change + if (currentColumn !== column) { + await this.api.changeColumn(draggedNote.noteId, column); + } + + // Handle position change (works for both same column and different column moves) + if (targetBranchId && moveType) { + if (moveType === "before") { + console.log("Move before branch:", draggedBranch.branchId, "to", targetBranchId); + await branchService.moveBeforeBranch([draggedBranch.branchId], targetBranchId); + } else if (moveType === "after") { + console.log("Move after branch:", draggedBranch.branchId, "to", targetBranchId); + await branchService.moveAfterBranch([draggedBranch.branchId], targetBranchId); + } + } + + // Update the data attributes + draggedNoteElement.attr("data-current-column", column); + + // Show success feedback + console.log(`Moved note "${draggedNote.title}" from "${currentColumn}" to "${column}"`); + + // Refresh the board to reflect the changes + await this.onBoardRefresh(); + } catch (error) { + console.error("Failed to update note position:", error); + } + } + } +} diff --git a/apps/client/src/widgets/view_widgets/board_view/index.ts b/apps/client/src/widgets/view_widgets/board_view/index.ts index b62f21794..23af7a8ee 100644 --- a/apps/client/src/widgets/view_widgets/board_view/index.ts +++ b/apps/client/src/widgets/view_widgets/board_view/index.ts @@ -1,13 +1,13 @@ import { setupHorizontalScrollViaWheel } from "../../widget_utils"; import ViewMode, { ViewModeArgs } from "../view_mode"; import attributeService from "../../../services/attributes"; -import branchService from "../../../services/branches"; import noteCreateService from "../../../services/note_create"; import appContext, { EventData } from "../../../components/app_context"; import { BoardData } from "./config"; import SpacedUpdate from "../../../services/spaced_update"; import { setupContextMenu } from "./context_menu"; import BoardApi from "./api"; +import { BoardDragHandler, DragContext } from "./drag_handler"; const TPL = /*html*/`
@@ -219,11 +219,10 @@ export default class BoardView extends ViewMode { private $root: JQuery; private $container: JQuery; private spacedUpdate: SpacedUpdate; - private draggedNote: any = null; - private draggedBranch: any = null; - private draggedNoteElement: JQuery | null = null; + private dragContext: DragContext; private persistentData: BoardData; private api?: BoardApi; + private dragHandler?: BoardDragHandler; constructor(args: ViewModeArgs) { super(args, "board"); @@ -235,6 +234,11 @@ export default class BoardView extends ViewMode { this.persistentData = { columns: [] }; + this.dragContext = { + draggedNote: null, + draggedBranch: null, + draggedNoteElement: null + }; args.$parent.append(this.$root); } @@ -248,6 +252,13 @@ export default class BoardView extends ViewMode { private async renderBoard(el: HTMLElement) { this.api = await BoardApi.build(this.parentNote, this.viewStorage); + this.dragHandler = new BoardDragHandler( + this.$container, + this.api, + this.dragContext, + async () => { await this.renderList(); } + ); + setupContextMenu({ $container: this.$container, api: this.api @@ -287,7 +298,7 @@ export default class BoardView extends ViewMode { }); // Setup drop zone for the column - this.setupColumnDropZone($columnEl, column); + this.dragHandler!.setupColumnDropZone($columnEl, column); for (const item of columnItems) { const note = item.note; @@ -311,7 +322,7 @@ export default class BoardView extends ViewMode { $noteEl.on("click", () => appContext.triggerCommand("openInPopup", { noteIdOrPath: note.noteId })); // Setup drag functionality for the note - this.setupNoteDrag($noteEl, note, branch); + this.dragHandler!.setupNoteDrag($noteEl, note, branch); $columnEl.append($noteEl); } @@ -344,373 +355,6 @@ export default class BoardView extends ViewMode { $(el).append($addColumnEl); } - private setupNoteDrag($noteEl: JQuery, note: any, branch: any) { - $noteEl.attr("draggable", "true"); - - // Mouse drag events - $noteEl.on("dragstart", (e) => { - this.draggedNote = note; - this.draggedBranch = branch; - this.draggedNoteElement = $noteEl; - $noteEl.addClass("dragging"); - - // Set drag data - const originalEvent = e.originalEvent as DragEvent; - if (originalEvent.dataTransfer) { - originalEvent.dataTransfer.effectAllowed = "move"; - originalEvent.dataTransfer.setData("text/plain", note.noteId); - } - }); - - $noteEl.on("dragend", () => { - $noteEl.removeClass("dragging"); - this.draggedNote = null; - this.draggedBranch = null; - this.draggedNoteElement = null; - - // Remove all drop indicators - this.$container.find(".board-drop-indicator").removeClass("show"); - }); - - // Touch drag events - let isDragging = false; - let startY = 0; - let startX = 0; - let dragThreshold = 10; // Minimum distance to start dragging - let $dragPreview: JQuery | null = null; - - $noteEl.on("touchstart", (e) => { - const touch = (e.originalEvent as TouchEvent).touches[0]; - startX = touch.clientX; - startY = touch.clientY; - isDragging = false; - $dragPreview = null; - }); - - $noteEl.on("touchmove", (e) => { - e.preventDefault(); // Prevent scrolling - const touch = (e.originalEvent as TouchEvent).touches[0]; - const deltaX = Math.abs(touch.clientX - startX); - const deltaY = Math.abs(touch.clientY - startY); - - // Start dragging if we've moved beyond threshold - if (!isDragging && (deltaX > dragThreshold || deltaY > dragThreshold)) { - isDragging = true; - this.draggedNote = note; - this.draggedBranch = branch; - this.draggedNoteElement = $noteEl; - $noteEl.addClass("dragging"); - - // Create drag preview - $dragPreview = this.createDragPreview($noteEl, touch.clientX, touch.clientY); - } - - if (isDragging && $dragPreview) { - // Update drag preview position - $dragPreview.css({ - left: touch.clientX - ($dragPreview.outerWidth() || 0) / 2, - top: touch.clientY - ($dragPreview.outerHeight() || 0) / 2 - }); - - // Find element under touch point - const elementBelow = document.elementFromPoint(touch.clientX, touch.clientY); - if (elementBelow) { - const $columnEl = $(elementBelow).closest('.board-column'); - - if ($columnEl.length > 0) { - // Remove drag-over from all columns - this.$container.find('.board-column').removeClass('drag-over'); - $columnEl.addClass('drag-over'); - - // Show drop indicator - this.showDropIndicatorAtPoint($columnEl, touch.clientY); - } else { - // Remove all drag indicators if not over a column - this.$container.find('.board-column').removeClass('drag-over'); - this.$container.find(".board-drop-indicator").removeClass("show"); - } - } - } - }); - - $noteEl.on("touchend", async (e) => { - if (isDragging) { - const touch = (e.originalEvent as TouchEvent).changedTouches[0]; - const elementBelow = document.elementFromPoint(touch.clientX, touch.clientY); - if (elementBelow) { - const $columnEl = $(elementBelow).closest('.board-column'); - - if ($columnEl.length > 0) { - const column = $columnEl.attr('data-column'); - if (column && this.draggedNote && this.draggedNoteElement && this.draggedBranch) { - await this.handleNoteDrop($columnEl, column); - } - } - } - - // Clean up - $noteEl.removeClass("dragging"); - this.draggedNote = null; - this.draggedBranch = null; - this.draggedNoteElement = null; - this.$container.find('.board-column').removeClass('drag-over'); - this.$container.find(".board-drop-indicator").removeClass("show"); - - // Remove drag preview - if ($dragPreview) { - $dragPreview.remove(); - $dragPreview = null; - } - } - isDragging = false; - }); - } - - private setupColumnDropZone($columnEl: JQuery, column: string) { - $columnEl.on("dragover", (e) => { - e.preventDefault(); - const originalEvent = e.originalEvent as DragEvent; - if (originalEvent.dataTransfer) { - originalEvent.dataTransfer.dropEffect = "move"; - } - - if (this.draggedNote) { - $columnEl.addClass("drag-over"); - this.showDropIndicator($columnEl, e); - } - }); - - $columnEl.on("dragleave", (e) => { - // Only remove drag-over if we're leaving the column entirely - const rect = $columnEl[0].getBoundingClientRect(); - const originalEvent = e.originalEvent as DragEvent; - const x = originalEvent.clientX; - const y = originalEvent.clientY; - - if (x < rect.left || x > rect.right || y < rect.top || y > rect.bottom) { - $columnEl.removeClass("drag-over"); - $columnEl.find(".board-drop-indicator").removeClass("show"); - } - }); - - $columnEl.on("drop", async (e) => { - e.preventDefault(); - $columnEl.removeClass("drag-over"); - - const draggedNoteElement = this.draggedNoteElement; - const draggedNote = this.draggedNote; - const draggedBranch = this.draggedBranch; - if (draggedNote && draggedNoteElement && draggedBranch) { - const currentColumn = draggedNoteElement.attr("data-current-column"); - - // Capture drop indicator position BEFORE removing it - const dropIndicator = $columnEl.find(".board-drop-indicator.show"); - let targetBranchId: string | null = null; - let moveType: "before" | "after" | null = null; - - if (dropIndicator.length > 0) { - // Find the note element that the drop indicator is positioned relative to - const nextNote = dropIndicator.next(".board-note"); - const prevNote = dropIndicator.prev(".board-note"); - - if (nextNote.length > 0) { - targetBranchId = nextNote.attr("data-branch-id") || null; - moveType = "before"; - } else if (prevNote.length > 0) { - targetBranchId = prevNote.attr("data-branch-id") || null; - moveType = "after"; - } - } - - // Now remove the drop indicator - $columnEl.find(".board-drop-indicator").removeClass("show"); - - try { - // Handle column change - if (currentColumn !== column) { - await this.api?.changeColumn(draggedNote.noteId, column); - } - - // Handle position change (works for both same column and different column moves) - if (targetBranchId && moveType) { - if (moveType === "before") { - console.log("Move before branch:", draggedBranch.branchId, "to", targetBranchId); - await branchService.moveBeforeBranch([draggedBranch.branchId], targetBranchId); - } else if (moveType === "after") { - console.log("Move after branch:", draggedBranch.branchId, "to", targetBranchId); - await branchService.moveAfterBranch([draggedBranch.branchId], targetBranchId); - } - } - - // Update the data attributes - draggedNoteElement.attr("data-current-column", column); - - // Show success feedback - console.log(`Moved note "${draggedNote.title}" from "${currentColumn}" to "${column}"`); - - // Refresh the board to reflect the changes - await this.renderList(); - } catch (error) { - console.error("Failed to update note position:", error); - } - } - }); - } - - private showDropIndicator($columnEl: JQuery, e: JQuery.DragOverEvent) { - const originalEvent = e.originalEvent as DragEvent; - const mouseY = originalEvent.clientY; - const columnRect = $columnEl[0].getBoundingClientRect(); - const relativeY = mouseY - columnRect.top; - - // Find existing drop indicator or create one - let $dropIndicator = $columnEl.find(".board-drop-indicator"); - if ($dropIndicator.length === 0) { - $dropIndicator = $("
").addClass("board-drop-indicator"); - $columnEl.append($dropIndicator); - } - - // Find the best position to insert the note - const $notes = this.draggedNoteElement ? - $columnEl.find(".board-note").not(this.draggedNoteElement) : - $columnEl.find(".board-note"); - let insertAfterElement: HTMLElement | null = null; - - $notes.each((_, noteEl) => { - const noteRect = noteEl.getBoundingClientRect(); - const noteMiddle = noteRect.top + noteRect.height / 2 - columnRect.top; - - if (relativeY > noteMiddle) { - insertAfterElement = noteEl; - } - }); - - // Position the drop indicator - if (insertAfterElement) { - $(insertAfterElement).after($dropIndicator); - } else { - // Insert at the beginning (after the header) - const $header = $columnEl.find("h3"); - $header.after($dropIndicator); - } - - $dropIndicator.addClass("show"); - } - - private showDropIndicatorAtPoint($columnEl: JQuery, touchY: number) { - const columnRect = $columnEl[0].getBoundingClientRect(); - const relativeY = touchY - columnRect.top; - - // Find existing drop indicator or create one - let $dropIndicator = $columnEl.find(".board-drop-indicator"); - if ($dropIndicator.length === 0) { - $dropIndicator = $("
").addClass("board-drop-indicator"); - $columnEl.append($dropIndicator); - } - - // Find the best position to insert the note - const $notes = this.draggedNoteElement ? - $columnEl.find(".board-note").not(this.draggedNoteElement) : - $columnEl.find(".board-note"); - let insertAfterElement: HTMLElement | null = null; - - $notes.each((_, noteEl) => { - const noteRect = noteEl.getBoundingClientRect(); - const noteMiddle = noteRect.top + noteRect.height / 2 - columnRect.top; - - if (relativeY > noteMiddle) { - insertAfterElement = noteEl; - } - }); - - // Position the drop indicator - if (insertAfterElement) { - $(insertAfterElement).after($dropIndicator); - } else { - // Insert at the beginning (after the header) - const $header = $columnEl.find("h3"); - $header.after($dropIndicator); - } - - $dropIndicator.addClass("show"); - } - - private createDragPreview($noteEl: JQuery, x: number, y: number): JQuery { - // Clone the note element for the preview - const $preview = $noteEl.clone(); - - $preview - .addClass('board-drag-preview') - .css({ - position: 'fixed', - left: x - ($noteEl.outerWidth() || 0) / 2, - top: y - ($noteEl.outerHeight() || 0) / 2, - pointerEvents: 'none', - zIndex: 10000 - }) - .appendTo('body'); - - return $preview; - } - - private async handleNoteDrop($columnEl: JQuery, column: string) { - const draggedNoteElement = this.draggedNoteElement; - const draggedNote = this.draggedNote; - const draggedBranch = this.draggedBranch; - - if (draggedNote && draggedNoteElement && draggedBranch) { - const currentColumn = draggedNoteElement.attr("data-current-column"); - - // Capture drop indicator position BEFORE removing it - const dropIndicator = $columnEl.find(".board-drop-indicator.show"); - let targetBranchId: string | null = null; - let moveType: "before" | "after" | null = null; - - if (dropIndicator.length > 0) { - // Find the note element that the drop indicator is positioned relative to - const nextNote = dropIndicator.next(".board-note"); - const prevNote = dropIndicator.prev(".board-note"); - - if (nextNote.length > 0) { - targetBranchId = nextNote.attr("data-branch-id") || null; - moveType = "before"; - } else if (prevNote.length > 0) { - targetBranchId = prevNote.attr("data-branch-id") || null; - moveType = "after"; - } - } - - try { - // Handle column change - if (currentColumn !== column) { - await this.api?.changeColumn(draggedNote.noteId, column); - } - - // Handle position change (works for both same column and different column moves) - if (targetBranchId && moveType) { - if (moveType === "before") { - console.log("Move before branch:", draggedBranch.branchId, "to", targetBranchId); - await branchService.moveBeforeBranch([draggedBranch.branchId], targetBranchId); - } else if (moveType === "after") { - console.log("Move after branch:", draggedBranch.branchId, "to", targetBranchId); - await branchService.moveAfterBranch([draggedBranch.branchId], targetBranchId); - } - } - - // Update the data attributes - draggedNoteElement.attr("data-current-column", column); - - // Show success feedback - console.log(`Moved note "${draggedNote.title}" from "${currentColumn}" to "${column}"`); - - // Refresh the board to reflect the changes - await this.renderList(); - } catch (error) { - console.error("Failed to update note position:", error); - } - } - } - private createTitleStructure(title: string): { $titleText: JQuery; $editIcon: JQuery } { const $titleText = $("").text(title); const $editIcon = $("")