mirror of
				https://github.com/zadam/trilium.git
				synced 2025-11-04 05:28:59 +01:00 
			
		
		
		
	chore(react/collections/table): add back insert above/below
This commit is contained in:
		
							parent
							
								
									68b8ba691f
								
							
						
					
					
						commit
						05973672e4
					
				@ -1,4 +1,5 @@
 | 
			
		||||
import { BoardViewData } from ".";
 | 
			
		||||
import appContext from "../../../components/app_context";
 | 
			
		||||
import FNote from "../../../entities/fnote";
 | 
			
		||||
import attributes from "../../../services/attributes";
 | 
			
		||||
import { executeBulkActions } from "../../../services/bulk_action";
 | 
			
		||||
@ -29,9 +30,9 @@ export default class BoardApi {
 | 
			
		||||
                title: "New item"
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            if (newNote) {
 | 
			
		||||
            if (newNote && newBranch) {
 | 
			
		||||
                await this.changeColumn(newNote.noteId, column);
 | 
			
		||||
                this.setBranchIdToEdit(newBranch?.branchId);
 | 
			
		||||
                this.startEditing(newBranch?.branchId);
 | 
			
		||||
            }
 | 
			
		||||
        } catch (error) {
 | 
			
		||||
            console.error("Failed to create new item:", error);
 | 
			
		||||
@ -56,6 +57,36 @@ export default class BoardApi {
 | 
			
		||||
        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() {
 | 
			
		||||
        this.setBranchIdToEdit(undefined);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -53,12 +53,12 @@ export function openNoteContextMenu(api: Api, event: ContextMenuEvent, noteId: s
 | 
			
		||||
            {
 | 
			
		||||
                title: t("board_view.insert-above"),
 | 
			
		||||
                uiIcon: "bx bx-list-plus",
 | 
			
		||||
                // handler: () => boardView.insertItemAtPosition(column, branchId, "before")
 | 
			
		||||
                handler: () => api.insertRowAtPosition(column, branchId, "before")
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                title: t("board_view.insert-below"),
 | 
			
		||||
                uiIcon: "bx bx-empty",
 | 
			
		||||
                // handler: () => boardView.insertItemAtPosition(column, branchId, "after")
 | 
			
		||||
                handler: () => api.insertRowAtPosition(column, branchId, "after")
 | 
			
		||||
            },
 | 
			
		||||
            { title: "----" },
 | 
			
		||||
            {
 | 
			
		||||
 | 
			
		||||
@ -29,35 +29,6 @@ export default class BoardApi {
 | 
			
		||||
        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[]) {
 | 
			
		||||
        // Change the value in the notes.
 | 
			
		||||
        await executeBulkActions(noteIds, [
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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() {
 | 
			
		||||
        this.renderer?.forceFullRender();
 | 
			
		||||
        return this.renderList();
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user