diff --git a/apps/client/src/widgets/collections/table/col_editing.ts b/apps/client/src/widgets/collections/table/col_editing.ts index 54c513d61..ca5636040 100644 --- a/apps/client/src/widgets/collections/table/col_editing.ts +++ b/apps/client/src/widgets/collections/table/col_editing.ts @@ -2,31 +2,27 @@ import { useLegacyImperativeHandlers } from "../../react/hooks"; import { Attribute } from "../../../services/attribute_parser"; import { RefObject } from "preact"; import { Tabulator } from "tabulator-tables"; -import { useEffect, useState } from "preact/hooks"; +import { useRef, useState } from "preact/hooks"; import { CommandListenerData, EventData } from "../../../components/app_context"; import AttributeDetailWidget from "../../attribute_widgets/attribute_detail"; import attributes from "../../../services/attributes"; import { renameColumn } from "../../view_widgets/table_view/bulk_actions"; import FNote from "../../../entities/fnote"; +import { getAttributeFromField } from "./utils"; export default function useColTableEditing(api: RefObject, attributeDetailWidget: AttributeDetailWidget, parentNote: FNote) { const [ existingAttributeToEdit, setExistingAttributeToEdit ] = useState(); - const [ newAttribute, setNewAttribute ] = useState(); - const [ newAttributePosition, setNewAttributePosition ] = useState(); - - useEffect(() => { - - }, []); + const newAttribute = useRef(); + const newAttributePosition = useRef(); useLegacyImperativeHandlers({ addNewTableColumnCommand({ referenceColumn, columnToEdit, direction, type }: EventData<"addNewTableColumn">) { - console.log("Ding"); let attr: Attribute | undefined; setExistingAttributeToEdit(undefined); if (columnToEdit) { - attr = this.getAttributeFromField(columnToEdit.getField()); + attr = getAttributeFromField(parentNote, columnToEdit.getField()); if (attr) { setExistingAttributeToEdit({ ...attr }); } @@ -47,9 +43,9 @@ export default function useColTableEditing(api: RefObject, attributeD newPosition++; } - setNewAttributePosition(newPosition); + newAttributePosition.current = newPosition; } else { - setNewAttributePosition(undefined); + newAttributePosition.current = undefined; } attributeDetailWidget.showAttributeDetail({ @@ -63,26 +59,26 @@ export default function useColTableEditing(api: RefObject, attributeD }); }, async updateAttributeListCommand({ attributes }: CommandListenerData<"updateAttributeList">) { - setNewAttribute(attributes[0]); + newAttribute.current = attributes[0]; }, async saveAttributesCommand() { - if (!newAttribute || !api.current) { + if (!newAttribute.current || !api.current) { return; } - const { name, value, isInheritable } = newAttribute; + const { name, value, isInheritable } = newAttribute.current; api.current.blockRedraw(); - const isRename = (this.existingAttributeToEdit && this.existingAttributeToEdit.name !== name); + const isRename = (existingAttributeToEdit && existingAttributeToEdit.name !== name); try { if (isRename) { - const oldName = this.existingAttributeToEdit!.name.split(":")[1]; + const oldName = existingAttributeToEdit!.name.split(":")[1]; const [ type, newName ] = name.split(":"); await renameColumn(parentNote.noteId, type as "label" | "relation", oldName, newName); } if (existingAttributeToEdit && (isRename || existingAttributeToEdit.isInheritable !== isInheritable)) { - attributes.removeOwnedLabelByName(parentNote, this.existingAttributeToEdit.name); + attributes.removeOwnedLabelByName(parentNote, existingAttributeToEdit.name); } attributes.setLabel(parentNote.noteId, name, value, isInheritable); } finally { @@ -91,5 +87,5 @@ export default function useColTableEditing(api: RefObject, attributeD } }); - return {}; + return { newAttributePosition }; } diff --git a/apps/client/src/widgets/collections/table/index.tsx b/apps/client/src/widgets/collections/table/index.tsx index dc6062baf..72dfeeb91 100644 --- a/apps/client/src/widgets/collections/table/index.tsx +++ b/apps/client/src/widgets/collections/table/index.tsx @@ -15,7 +15,7 @@ import useRowTableEditing, { canReorderRows } from "./row_editing"; import useColTableEditing from "./col_editing"; import AttributeDetailWidget from "../../attribute_widgets/attribute_detail"; import attributes from "../../../services/attributes"; -import { refreshTextDimensions } from "@excalidraw/excalidraw/element/newElement"; +import { RefObject } from "preact"; interface TableConfig { tableData?: { @@ -24,48 +24,15 @@ interface TableConfig { } export default function TableView({ note, noteIds, notePath, viewConfig, saveConfig }: ViewModeProps) { - const [ maxDepth ] = useNoteLabelInt(note, "maxNestingDepth") ?? -1; - const [ columnDefs, setColumnDefs ] = useState(); - const [ rowData, setRowData ] = useState(); - const [ movableRows, setMovableRows ] = useState(); - const [ hasChildren, setHasChildren ] = useState(); const tabulatorRef = useRef(null); const parentComponent = useContext(ParentComponent); - function refresh() { - const info = getAttributeDefinitionInformation(note); - buildRowDefinitions(note, info, maxDepth).then(({ definitions: rowData, hasSubtree: hasChildren, rowNumber }) => { - const movableRows = canReorderRows(note) && !hasChildren; - const columnDefs = buildColumnDefinitions({ - info, - movableRows, - existingColumnData: viewConfig?.tableData?.columns, - rowNumberHint: rowNumber - }); - setColumnDefs(columnDefs); - setRowData(rowData); - setMovableRows(movableRows); - setHasChildren(hasChildren); - }); - } - - useEffect(refresh, [ note, noteIds ]); - - // React to column changes. - useTriliumEvent("entitiesReloaded", ({ loadResults}) => { - if (loadResults.getAttributeRows().find(attr => - attr.type === "label" && - (attr.name?.startsWith("label:") || attr.name?.startsWith("relation:")) && - attributes.isAffecting(attr, note))) { - refresh(); - } - }); - const [ attributeDetailWidgetEl, attributeDetailWidget ] = useLegacyWidget(() => new AttributeDetailWidget().contentSized()); const contextMenuEvents = useContextMenu(note, parentComponent, tabulatorRef); const persistenceProps = usePersistence(viewConfig, saveConfig); const rowEditingEvents = useRowTableEditing(tabulatorRef, attributeDetailWidget, notePath); - const colEditingEvents = useColTableEditing(tabulatorRef, attributeDetailWidget, note); + const { newAttributePosition } = useColTableEditing(tabulatorRef, attributeDetailWidget, note); + const { columnDefs, rowData, movableRows, hasChildren } = useData(note, noteIds, viewConfig, newAttributePosition); const dataTreeProps = useMemo(() => { if (!hasChildren) return {}; return { @@ -92,8 +59,7 @@ export default function TableView({ note, noteIds, notePath, viewConfig, saveCon footerElement={} events={{ ...contextMenuEvents, - ...rowEditingEvents, - ...colEditingEvents + ...rowEditingEvents }} persistence {...persistenceProps} layout="fitDataFill" @@ -141,3 +107,44 @@ function usePersistence(initialConfig: TableConfig | null | undefined, saveConfi }, []); return { persistenceReaderFunc, persistenceWriterFunc }; } + +function useData(note: FNote, noteIds: string[], viewConfig: TableConfig | undefined, newAttributePosition: RefObject) { + const [ maxDepth ] = useNoteLabelInt(note, "maxNestingDepth") ?? -1; + + const [ columnDefs, setColumnDefs ] = useState(); + const [ rowData, setRowData ] = useState(); + const [ movableRows, setMovableRows ] = useState(); + const [ hasChildren, setHasChildren ] = useState(); + + function refresh() { + const info = getAttributeDefinitionInformation(note); + buildRowDefinitions(note, info, maxDepth).then(({ definitions: rowData, hasSubtree: hasChildren, rowNumber }) => { + const movableRows = canReorderRows(note) && !hasChildren; + const columnDefs = buildColumnDefinitions({ + info, + movableRows, + existingColumnData: viewConfig?.tableData?.columns, + rowNumberHint: rowNumber, + position: newAttributePosition.current ?? undefined + }); + setColumnDefs(columnDefs); + setRowData(rowData); + setMovableRows(movableRows); + setHasChildren(hasChildren); + }); + } + + useEffect(refresh, [ note, noteIds ]); + + // React to column changes. + useTriliumEvent("entitiesReloaded", ({ loadResults}) => { + if (loadResults.getAttributeRows().find(attr => + attr.type === "label" && + (attr.name?.startsWith("label:") || attr.name?.startsWith("relation:")) && + attributes.isAffecting(attr, note))) { + refresh(); + } + }); + + return { columnDefs, rowData, movableRows, hasChildren }; +} diff --git a/apps/client/src/widgets/collections/table/utils.ts b/apps/client/src/widgets/collections/table/utils.ts new file mode 100644 index 000000000..3daae04da --- /dev/null +++ b/apps/client/src/widgets/collections/table/utils.ts @@ -0,0 +1,21 @@ +import FNote from "../../../entities/fnote"; +import { Attribute } from "../../../services/attribute_parser"; + +export function getFAttributeFromField(parentNote: FNote, field: string) { + const [ type, name ] = field.split(".", 2); + const attrName = `${type.replace("s", "")}:${name}`; + return parentNote.getLabel(attrName); +} + +export function getAttributeFromField(parentNote: FNote, field: string): Attribute | undefined { + const fAttribute = getFAttributeFromField(parentNote, field); + if (fAttribute) { + return { + name: fAttribute.name, + value: fAttribute.value, + type: fAttribute.type, + isInheritable: fAttribute.isInheritable + }; + } + return undefined; +} diff --git a/apps/client/src/widgets/view_widgets/table_view/col_editing.ts b/apps/client/src/widgets/view_widgets/table_view/col_editing.ts index 4114fdf5c..cf520303d 100644 --- a/apps/client/src/widgets/view_widgets/table_view/col_editing.ts +++ b/apps/client/src/widgets/view_widgets/table_view/col_editing.ts @@ -52,23 +52,6 @@ export default class TableColumnEditing extends Component { this.existingAttributeToEdit = undefined; } - getFAttributeFromField(field: string) { - const [ type, name ] = field.split(".", 2); - const attrName = `${type.replace("s", "")}:${name}`; - return this.parentNote.getLabel(attrName); - } - getAttributeFromField(field: string): Attribute | undefined { - const fAttribute = this.getFAttributeFromField(field); - if (fAttribute) { - return { - name: fAttribute.name, - value: fAttribute.value, - type: fAttribute.type, - isInheritable: fAttribute.isInheritable - }; - } - return undefined; - } } diff --git a/apps/client/src/widgets/view_widgets/table_view/index.ts b/apps/client/src/widgets/view_widgets/table_view/index.ts index ef80dab80..479e6f90b 100644 --- a/apps/client/src/widgets/view_widgets/table_view/index.ts +++ b/apps/client/src/widgets/view_widgets/table_view/index.ts @@ -123,11 +123,7 @@ export default class TableView extends ViewMode { this.colEditing?.resetNewAttributePosition(); } - addNewRowCommand(e) { this.rowEditing?.addNewRowCommand(e); } - addNewTableColumnCommand(e) { this.colEditing?.addNewTableColumnCommand(e); } deleteTableColumnCommand(e) { this.colEditing?.deleteTableColumnCommand(e); } - updateAttributeListCommand(e) { this.colEditing?.updateAttributeListCommand(e); } - saveAttributesCommand() { this.colEditing?.saveAttributesCommand(); } async #manageRowsUpdate() { if (!this.api) {