chore(react/collections/table): add back insert above/below

This commit is contained in:
Elian Doran
2025-09-11 21:11:44 +03:00
parent 68b8ba691f
commit 05973672e4
5 changed files with 36 additions and 151 deletions

View File

@@ -1,4 +1,5 @@
import { BoardViewData } from "."; import { BoardViewData } from ".";
import appContext from "../../../components/app_context";
import FNote from "../../../entities/fnote"; import FNote from "../../../entities/fnote";
import attributes from "../../../services/attributes"; import attributes from "../../../services/attributes";
import { executeBulkActions } from "../../../services/bulk_action"; import { executeBulkActions } from "../../../services/bulk_action";
@@ -29,9 +30,9 @@ export default class BoardApi {
title: "New item" title: "New item"
}); });
if (newNote) { if (newNote && newBranch) {
await this.changeColumn(newNote.noteId, column); await this.changeColumn(newNote.noteId, column);
this.setBranchIdToEdit(newBranch?.branchId); this.startEditing(newBranch?.branchId);
} }
} catch (error) { } catch (error) {
console.error("Failed to create new item:", error); console.error("Failed to create new item:", error);
@@ -56,6 +57,36 @@ export default class BoardApi {
this.saveConfig(this.viewConfig); this.saveConfig(this.viewConfig);
} }
async insertRowAtPosition(
column: string,
relativeToBranchId: string,
direction: "before" | "after") {
const { note, branch } = await note_create.createNote(this.parentNote.noteId, {
activate: false,
targetBranchId: relativeToBranchId,
target: direction,
title: "New item"
});
if (!note || !branch) {
throw new Error("Failed to create note");
}
const { noteId } = note;
await this.changeColumn(noteId, column);
this.startEditing(branch.branchId);
return note;
}
openNote(noteId: string) {
appContext.triggerCommand("openInPopup", { noteIdOrPath: noteId });
}
startEditing(branchId: string) {
this.setBranchIdToEdit(branchId);
}
dismissEditingTitle() { dismissEditingTitle() {
this.setBranchIdToEdit(undefined); this.setBranchIdToEdit(undefined);
} }

View File

@@ -53,12 +53,12 @@ export function openNoteContextMenu(api: Api, event: ContextMenuEvent, noteId: s
{ {
title: t("board_view.insert-above"), title: t("board_view.insert-above"),
uiIcon: "bx bx-list-plus", uiIcon: "bx bx-list-plus",
// handler: () => boardView.insertItemAtPosition(column, branchId, "before") handler: () => api.insertRowAtPosition(column, branchId, "before")
}, },
{ {
title: t("board_view.insert-below"), title: t("board_view.insert-below"),
uiIcon: "bx bx-empty", uiIcon: "bx bx-empty",
// handler: () => boardView.insertItemAtPosition(column, branchId, "after") handler: () => api.insertRowAtPosition(column, branchId, "after")
}, },
{ title: "----" }, { title: "----" },
{ {

View File

@@ -29,35 +29,6 @@ export default class BoardApi {
return this.byColumn.get(column); return this.byColumn.get(column);
} }
openNote(noteId: string) {
appContext.triggerCommand("openInPopup", { noteIdOrPath: noteId });
}
async insertRowAtPosition(
column: string,
relativeToBranchId: string,
direction: "before" | "after",
open: boolean = true) {
const { note } = await note_create.createNote(this._parentNoteId, {
activate: false,
targetBranchId: relativeToBranchId,
target: direction,
title: "New item"
});
if (!note) {
throw new Error("Failed to create note");
}
const { noteId } = note;
await this.changeColumn(noteId, column);
if (open) {
this.openNote(noteId);
}
return note;
}
async renameColumn(oldValue: string, newValue: string, noteIds: string[]) { async renameColumn(oldValue: string, newValue: string, noteIds: string[]) {
// Change the value in the notes. // Change the value in the notes.
await executeBulkActions(noteIds, [ await executeBulkActions(noteIds, [
@@ -80,7 +51,7 @@ export default class BoardApi {
async reorderColumns(newColumnOrder: string[]) { async reorderColumns(newColumnOrder: string[]) {
// Update the column order in persisted data // Update the co lumn order in persisted data
if (!this.persistedData.columns) { if (!this.persistedData.columns) {
this.persistedData.columns = []; this.persistedData.columns = [];
} }

View File

@@ -380,100 +380,4 @@ export class DifferentialBoardRenderer {
} }
} }
startInlineEditing(noteId: string): void {
// Use setTimeout to ensure the card is rendered before trying to edit it
setTimeout(() => {
const $card = this.$container.find(`[data-note-id="${noteId}"]`);
if ($card.length) {
this.makeCardEditable($card, noteId);
}
}, 100);
}
private makeCardEditable($card: JQuery<HTMLElement>, noteId: string): void {
if ($card.hasClass('editing')) {
return; // Already editing
}
// Get the current title (get text without icon)
const $icon = $card.find('.icon');
const currentTitle = $card.text().trim();
// Add editing class and store original click handler
$card.addClass('editing');
$card.off('click'); // Remove any existing click handlers temporarily
// Create input element
const $input = $('<input>')
.attr('type', 'text')
.val(currentTitle)
.css({
background: 'transparent',
border: 'none',
outline: 'none',
fontFamily: 'inherit',
fontSize: 'inherit',
color: 'inherit',
flex: '1',
minWidth: '0',
padding: '0',
marginLeft: '0.25em'
});
// Create a flex container to keep icon and input inline
const $editContainer = $('<div>')
.css({
display: 'flex',
alignItems: 'center',
width: '100%'
});
// Replace content with icon + input in flex container
$editContainer.append($icon.clone(), $input);
$card.empty().append($editContainer);
$input.focus().select();
const finishEdit = async (save = true) => {
if (!$card.hasClass('editing')) {
return; // Already finished
}
$card.removeClass('editing');
let finalTitle = currentTitle;
if (save) {
const newTitle = $input.val() as string;
if (newTitle.trim() && newTitle !== currentTitle) {
try {
// Update the note title using the board view's server call
import('../../../services/server').then(async ({ default: server }) => {
});
} catch (error) {
console.error("Failed to update note title:", error);
}
}
}
// Restore the card content
const iconClass = $card.attr('data-icon-class') || 'bx bx-file';
const $newIcon = $('<span>').addClass('icon').addClass(iconClass);
$card.text(finalTitle);
$card.prepend($newIcon);
// Re-attach click handler for quick edit (for existing cards)
$card.on('click', () => appContext.triggerCommand("openInPopup", { noteIdOrPath: noteId }));
};
$input.on('blur', () => finishEdit(true));
$input.on('keydown', (e) => {
if (e.key === 'Enter') {
e.preventDefault();
finishEdit(true);
} else if (e.key === 'Escape') {
e.preventDefault();
finishEdit(false);
}
});
}
} }

View File

@@ -219,27 +219,6 @@ export default class BoardView extends ViewMode<BoardData> {
} }
} }
async insertItemAtPosition(column: string, relativeToBranchId: string, direction: "before" | "after"): Promise<void> {
try {
// Create the note without opening it
const newNote = await this.api?.insertRowAtPosition(column, relativeToBranchId, direction, false);
if (newNote) {
// Refresh the board to show the new item
await this.renderList();
// Start inline editing of the newly created card
this.startInlineEditingCard(newNote.noteId);
}
} catch (error) {
console.error("Failed to insert new item:", error);
}
}
private startInlineEditingCard(noteId: string) {
this.renderer?.startInlineEditing(noteId);
}
forceFullRefresh() { forceFullRefresh() {
this.renderer?.forceFullRender(); this.renderer?.forceFullRender();
return this.renderList(); return this.renderList();