chore(react/collections/table): bring back renaming columns

This commit is contained in:
Elian Doran 2025-09-11 21:34:10 +03:00
parent d367cf9972
commit 60ef816f0c
No known key found for this signature in database
5 changed files with 82 additions and 40 deletions

View File

@ -57,6 +57,27 @@ export default class BoardApi {
this.saveConfig(this.viewConfig); 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( async insertRowAtPosition(
column: string, column: string,
relativeToBranchId: string, relativeToBranchId: string,

View File

@ -54,6 +54,10 @@
cursor: default; cursor: default;
} }
.board-view-container .board-column h3.editing input {
padding: 0;
}
.board-view-container .board-column h3:hover { .board-view-container .board-column h3:hover {
background-color: var(--hover-item-background-color); background-color: var(--hover-item-background-color);
border-radius: 4px; border-radius: 4px;

View File

@ -25,6 +25,8 @@ export interface BoardColumnData {
interface BoardViewContextData { interface BoardViewContextData {
branchIdToEdit?: string; branchIdToEdit?: string;
columnNameToEdit?: string;
setColumnNameToEdit?: (column: string | undefined) => void;
} }
const BoardViewContext = createContext<BoardViewContextData>({}); const BoardViewContext = createContext<BoardViewContextData>({});
@ -39,12 +41,15 @@ export default function BoardView({ note: parentNote, noteIds, viewConfig, saveC
const [ draggedColumn, setDraggedColumn ] = useState<{ column: string, index: number } | null>(null); const [ draggedColumn, setDraggedColumn ] = useState<{ column: string, index: number } | null>(null);
const [ columnDropPosition, setColumnDropPosition ] = useState<number | null>(null); const [ columnDropPosition, setColumnDropPosition ] = useState<number | null>(null);
const [ branchIdToEdit, setBranchIdToEdit ] = useState<string>(); const [ branchIdToEdit, setBranchIdToEdit ] = useState<string>();
const [ columnNameToEdit, setColumnNameToEdit ] = useState<string>();
const api = useMemo(() => { const api = useMemo(() => {
return new Api(byColumn, columns ?? [], parentNote, statusAttribute, viewConfig ?? {}, saveConfig, setBranchIdToEdit ); return new Api(byColumn, columns ?? [], parentNote, statusAttribute, viewConfig ?? {}, saveConfig, setBranchIdToEdit );
}, [ byColumn, columns, parentNote, statusAttribute, viewConfig, saveConfig, setBranchIdToEdit ]); }, [ byColumn, columns, parentNote, statusAttribute, viewConfig, saveConfig, setBranchIdToEdit ]);
const boardViewContext = useMemo<BoardViewContextData>(() => ({ const boardViewContext = useMemo<BoardViewContextData>(() => ({
branchIdToEdit branchIdToEdit,
}), [ branchIdToEdit ]); columnNameToEdit,
setColumnNameToEdit
}), [ branchIdToEdit, columnNameToEdit, setColumnNameToEdit ]);
function refresh() { function refresh() {
getBoardData(parentNote, statusAttribute, viewConfig ?? {}).then(({ byColumn, newPersistedData }) => { getBoardData(parentNote, statusAttribute, viewConfig ?? {}).then(({ byColumn, newPersistedData }) => {
@ -214,6 +219,10 @@ function Column({
isDraggingColumn: boolean, isDraggingColumn: boolean,
api: Api api: Api
}) { }) {
const context = useContext(BoardViewContext);
const isEditing = (context.columnNameToEdit === column);
const editorRef = useRef<HTMLInputElement>(null);
const handleColumnDragStart = useCallback((e: DragEvent) => { const handleColumnDragStart = useCallback((e: DragEvent) => {
e.dataTransfer!.effectAllowed = 'move'; e.dataTransfer!.effectAllowed = 'move';
e.dataTransfer!.setData('text/plain', column); e.dataTransfer!.setData('text/plain', column);
@ -301,10 +310,18 @@ function Column({
setDraggedCard(null); setDraggedCard(null);
}, [draggedCard, draggedColumn, dropPosition, columnItems, column, statusAttribute, setDraggedCard, setDropTarget, setDropPosition, onCardDrop]); }, [draggedCard, draggedColumn, dropPosition, columnItems, column, statusAttribute, setDraggedCard, setDropTarget, setDropPosition, onCardDrop]);
const handleEdit = useCallback(() => {
context.setColumnNameToEdit?.(column);
}, [column]);
const handleContextMenu = useCallback((e: ContextMenuEvent) => { const handleContextMenu = useCallback((e: ContextMenuEvent) => {
openColumnContextMenu(api, e, column); openColumnContextMenu(api, e, column);
}, [ api, column ]); }, [ api, column ]);
useEffect(() => {
editorRef.current?.focus();
}, [ isEditing ]);
return ( return (
<div <div
className={`board-column ${dropTarget === column && draggedCard?.fromColumn !== column ? 'drag-over' : ''} ${isDraggingColumn ? 'column-dragging' : ''}`} className={`board-column ${dropTarget === column && draggedCard?.fromColumn !== column ? 'drag-over' : ''} ${isDraggingColumn ? 'column-dragging' : ''}`}
@ -314,14 +331,47 @@ function Column({
onContextMenu={handleContextMenu} onContextMenu={handleContextMenu}
> >
<h3 <h3
className={`${isEditing ? "editing" : ""}`}
draggable="true" draggable="true"
onDragStart={handleColumnDragStart} onDragStart={handleColumnDragStart}
onDragEnd={handleColumnDragEnd} onDragEnd={handleColumnDragEnd}
> >
{!isEditing ? (
<>
<span>{column}</span> <span>{column}</span>
<span <span
className="edit-icon icon bx bx-edit-alt" className="edit-icon icon bx bx-edit-alt"
title="Click to edit column title" /> title="Click to edit column title"
onClick={handleEdit}
/>
</>
) : (
<>
<FormTextBox
inputRef={editorRef}
currentValue={column}
onKeyDown={(e) => {
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);
}}
/>
</>
)}
</h3> </h3>
{(columnItems ?? []).map(({ note, branch }, index) => { {(columnItems ?? []).map(({ note, branch }, index) => {
@ -396,7 +446,7 @@ function Card({
useEffect(() => { useEffect(() => {
editorRef.current?.focus(); editorRef.current?.focus();
}, []); }, [ isEditing ]);
return ( return (
<div <div

View File

@ -29,27 +29,6 @@ export default class BoardApi {
return this.byColumn.get(column); return this.byColumn.get(column);
} }
async renameColumn(oldValue: string, newValue: string, noteIds: string[]) {
// 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.persistedData.columns || []) {
if (column.value === oldValue) {
column.value = newValue;
}
}
await this.viewStorage.store(this.persistedData);
}
async reorderColumns(newColumnOrder: string[]) { async reorderColumns(newColumnOrder: string[]) {
// Update the co lumn order in persisted data // Update the co lumn order in persisted data
if (!this.persistedData.columns) { if (!this.persistedData.columns) {

View File

@ -135,15 +135,6 @@ export default class BoardView extends ViewMode<BoardData> {
}); });
} }
private createTitleStructure(title: string): { $titleText: JQuery<HTMLElement>; $editIcon: JQuery<HTMLElement> } {
const $titleText = $("<span>").text(title);
const $editIcon = $("<span>")
.addClass("edit-icon icon bx bx-edit-alt")
.attr("title", "Click to edit column title");
return { $titleText, $editIcon };
}
private startEditingColumnTitle($titleEl: JQuery<HTMLElement>, columnValue: string, columnItems: { branch: any; note: any; }[]) { private startEditingColumnTitle($titleEl: JQuery<HTMLElement>, columnValue: string, columnItems: { branch: any; note: any; }[]) {
if ($titleEl.hasClass("editing")) { if ($titleEl.hasClass("editing")) {
return; // Already editing return; // Already editing
@ -261,8 +252,5 @@ export default class BoardView extends ViewMode<BoardData> {
} }
} }
private onSave() {
this.viewStorage.store(this.persistentData);
}
} }