From 60ef816f0cbf80a6cdb8b0ee4af2126175710cd7 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Thu, 11 Sep 2025 21:34:10 +0300 Subject: [PATCH] chore(react/collections/table): bring back renaming columns --- .../src/widgets/collections/board/api.ts | 21 ++++++ .../src/widgets/collections/board/index.css | 4 ++ .../src/widgets/collections/board/index.tsx | 64 +++++++++++++++++-- .../widgets/view_widgets/board_view/api.ts | 21 ------ .../widgets/view_widgets/board_view/index.ts | 12 ---- 5 files changed, 82 insertions(+), 40 deletions(-) diff --git a/apps/client/src/widgets/collections/board/api.ts b/apps/client/src/widgets/collections/board/api.ts index f70a8d00d..210c2fb92 100644 --- a/apps/client/src/widgets/collections/board/api.ts +++ b/apps/client/src/widgets/collections/board/api.ts @@ -57,6 +57,27 @@ export default class BoardApi { this.saveConfig(this.viewConfig); } + async renameColumn(oldValue: string, newValue: string) { + const noteIds = this.byColumn?.get(oldValue)?.map(item => item.note.noteId) || []; + + // Change the value in the notes. + await executeBulkActions(noteIds, [ + { + name: "updateLabelValue", + labelName: this.statusAttribute, + labelValue: newValue + } + ]); + + // Rename the column in the persisted data. + for (const column of this.viewConfig.columns || []) { + if (column.value === oldValue) { + column.value = newValue; + } + } + this.saveConfig(this.viewConfig); + } + async insertRowAtPosition( column: string, relativeToBranchId: string, diff --git a/apps/client/src/widgets/collections/board/index.css b/apps/client/src/widgets/collections/board/index.css index c620ab0bc..6e002ba20 100644 --- a/apps/client/src/widgets/collections/board/index.css +++ b/apps/client/src/widgets/collections/board/index.css @@ -54,6 +54,10 @@ cursor: default; } +.board-view-container .board-column h3.editing input { + padding: 0; +} + .board-view-container .board-column h3:hover { background-color: var(--hover-item-background-color); border-radius: 4px; diff --git a/apps/client/src/widgets/collections/board/index.tsx b/apps/client/src/widgets/collections/board/index.tsx index 5c2c44603..2acbfe82d 100644 --- a/apps/client/src/widgets/collections/board/index.tsx +++ b/apps/client/src/widgets/collections/board/index.tsx @@ -25,6 +25,8 @@ export interface BoardColumnData { interface BoardViewContextData { branchIdToEdit?: string; + columnNameToEdit?: string; + setColumnNameToEdit?: (column: string | undefined) => void; } const BoardViewContext = createContext({}); @@ -39,12 +41,15 @@ export default function BoardView({ note: parentNote, noteIds, viewConfig, saveC const [ draggedColumn, setDraggedColumn ] = useState<{ column: string, index: number } | null>(null); const [ columnDropPosition, setColumnDropPosition ] = useState(null); const [ branchIdToEdit, setBranchIdToEdit ] = useState(); + const [ columnNameToEdit, setColumnNameToEdit ] = useState(); const api = useMemo(() => { return new Api(byColumn, columns ?? [], parentNote, statusAttribute, viewConfig ?? {}, saveConfig, setBranchIdToEdit ); }, [ byColumn, columns, parentNote, statusAttribute, viewConfig, saveConfig, setBranchIdToEdit ]); const boardViewContext = useMemo(() => ({ - branchIdToEdit - }), [ branchIdToEdit ]); + branchIdToEdit, + columnNameToEdit, + setColumnNameToEdit + }), [ branchIdToEdit, columnNameToEdit, setColumnNameToEdit ]); function refresh() { getBoardData(parentNote, statusAttribute, viewConfig ?? {}).then(({ byColumn, newPersistedData }) => { @@ -214,6 +219,10 @@ function Column({ isDraggingColumn: boolean, api: Api }) { + const context = useContext(BoardViewContext); + const isEditing = (context.columnNameToEdit === column); + const editorRef = useRef(null); + const handleColumnDragStart = useCallback((e: DragEvent) => { e.dataTransfer!.effectAllowed = 'move'; e.dataTransfer!.setData('text/plain', column); @@ -301,10 +310,18 @@ function Column({ setDraggedCard(null); }, [draggedCard, draggedColumn, dropPosition, columnItems, column, statusAttribute, setDraggedCard, setDropTarget, setDropPosition, onCardDrop]); + const handleEdit = useCallback(() => { + context.setColumnNameToEdit?.(column); + }, [column]); + const handleContextMenu = useCallback((e: ContextMenuEvent) => { openColumnContextMenu(api, e, column); }, [ api, column ]); + useEffect(() => { + editorRef.current?.focus(); + }, [ isEditing ]); + return (

- {column} - + {!isEditing ? ( + <> + {column} + + + ) : ( + <> + { + if (e.key === "Enter") { + const newTitle = e.currentTarget.value; + if (newTitle !== column) { + api.renameColumn(column, newTitle); + } + context.setColumnNameToEdit?.(undefined); + } + + if (e.key === "Escape") { + context.setColumnNameToEdit?.(undefined); + } + }} + onBlur={(newTitle) => { + if (newTitle !== column) { + api.renameColumn(column, newTitle); + } + context.setColumnNameToEdit?.(undefined); + }} + /> + + )}

{(columnItems ?? []).map(({ note, branch }, index) => { @@ -396,7 +446,7 @@ function Card({ useEffect(() => { editorRef.current?.focus(); - }, []); + }, [ isEditing ]); return (
{ }); } - private createTitleStructure(title: string): { $titleText: JQuery; $editIcon: JQuery } { - const $titleText = $("").text(title); - const $editIcon = $("") - .addClass("edit-icon icon bx bx-edit-alt") - .attr("title", "Click to edit column title"); - - return { $titleText, $editIcon }; - } - private startEditingColumnTitle($titleEl: JQuery, columnValue: string, columnItems: { branch: any; note: any; }[]) { if ($titleEl.hasClass("editing")) { return; // Already editing @@ -261,8 +252,5 @@ export default class BoardView extends ViewMode { } } - private onSave() { - this.viewStorage.store(this.persistentData); - } }