mirror of
https://github.com/zadam/trilium.git
synced 2025-10-29 02:28:57 +01:00
chore(react/collections/table): integrate cleanup
This commit is contained in:
parent
3046cfd6ee
commit
32ce6e7a08
@ -2,7 +2,7 @@ import { useLegacyImperativeHandlers } from "../../react/hooks";
|
|||||||
import { Attribute } from "../../../services/attribute_parser";
|
import { Attribute } from "../../../services/attribute_parser";
|
||||||
import { RefObject } from "preact";
|
import { RefObject } from "preact";
|
||||||
import { Tabulator } from "tabulator-tables";
|
import { Tabulator } from "tabulator-tables";
|
||||||
import { useRef, useState } from "preact/hooks";
|
import { useRef } from "preact/hooks";
|
||||||
import { CommandListenerData, EventData } from "../../../components/app_context";
|
import { CommandListenerData, EventData } from "../../../components/app_context";
|
||||||
import AttributeDetailWidget from "../../attribute_widgets/attribute_detail";
|
import AttributeDetailWidget from "../../attribute_widgets/attribute_detail";
|
||||||
import attributes from "../../../services/attributes";
|
import attributes from "../../../services/attributes";
|
||||||
@ -14,7 +14,7 @@ import { executeBulkActions } from "../../../services/bulk_action";
|
|||||||
|
|
||||||
export default function useColTableEditing(api: RefObject<Tabulator>, attributeDetailWidget: AttributeDetailWidget, parentNote: FNote) {
|
export default function useColTableEditing(api: RefObject<Tabulator>, attributeDetailWidget: AttributeDetailWidget, parentNote: FNote) {
|
||||||
|
|
||||||
const [ existingAttributeToEdit, setExistingAttributeToEdit ] = useState<Attribute>();
|
const existingAttributeToEdit = useRef<Attribute>();
|
||||||
const newAttribute = useRef<Attribute>();
|
const newAttribute = useRef<Attribute>();
|
||||||
const newAttributePosition = useRef<number>();
|
const newAttributePosition = useRef<number>();
|
||||||
|
|
||||||
@ -22,11 +22,11 @@ export default function useColTableEditing(api: RefObject<Tabulator>, attributeD
|
|||||||
addNewTableColumnCommand({ referenceColumn, columnToEdit, direction, type }: EventData<"addNewTableColumn">) {
|
addNewTableColumnCommand({ referenceColumn, columnToEdit, direction, type }: EventData<"addNewTableColumn">) {
|
||||||
let attr: Attribute | undefined;
|
let attr: Attribute | undefined;
|
||||||
|
|
||||||
setExistingAttributeToEdit(undefined);
|
existingAttributeToEdit.current = undefined;
|
||||||
if (columnToEdit) {
|
if (columnToEdit) {
|
||||||
attr = getAttributeFromField(parentNote, columnToEdit.getField());
|
attr = getAttributeFromField(parentNote, columnToEdit.getField());
|
||||||
if (attr) {
|
if (attr) {
|
||||||
setExistingAttributeToEdit({ ...attr });
|
existingAttributeToEdit.current = { ...attr };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,16 +71,16 @@ export default function useColTableEditing(api: RefObject<Tabulator>, attributeD
|
|||||||
const { name, value, isInheritable } = newAttribute.current;
|
const { name, value, isInheritable } = newAttribute.current;
|
||||||
|
|
||||||
api.current.blockRedraw();
|
api.current.blockRedraw();
|
||||||
const isRename = (existingAttributeToEdit && existingAttributeToEdit.name !== name);
|
const isRename = (existingAttributeToEdit.current && existingAttributeToEdit.current.name !== name);
|
||||||
try {
|
try {
|
||||||
if (isRename) {
|
if (isRename) {
|
||||||
const oldName = existingAttributeToEdit!.name.split(":")[1];
|
const oldName = existingAttributeToEdit.current!.name.split(":")[1];
|
||||||
const [ type, newName ] = name.split(":");
|
const [ type, newName ] = name.split(":");
|
||||||
await renameColumn(parentNote.noteId, type as "label" | "relation", oldName, newName);
|
await renameColumn(parentNote.noteId, type as "label" | "relation", oldName, newName);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (existingAttributeToEdit && (isRename || existingAttributeToEdit.isInheritable !== isInheritable)) {
|
if (existingAttributeToEdit.current && (isRename || existingAttributeToEdit.current.isInheritable !== isInheritable)) {
|
||||||
attributes.removeOwnedLabelByName(parentNote, existingAttributeToEdit.name);
|
attributes.removeOwnedLabelByName(parentNote, existingAttributeToEdit.current.name);
|
||||||
}
|
}
|
||||||
attributes.setLabel(parentNote.noteId, name, value, isInheritable);
|
attributes.setLabel(parentNote.noteId, name, value, isInheritable);
|
||||||
} finally {
|
} finally {
|
||||||
@ -108,7 +108,13 @@ export default function useColTableEditing(api: RefObject<Tabulator>, attributeD
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return { newAttributePosition };
|
function resetNewAttributePosition() {
|
||||||
|
newAttribute.current = undefined;
|
||||||
|
newAttributePosition.current = undefined;
|
||||||
|
existingAttributeToEdit.current = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return { newAttributePosition, resetNewAttributePosition };
|
||||||
}
|
}
|
||||||
|
|
||||||
async function deleteColumn(parentNoteId: string, type: "label" | "relation", columnName: string) {
|
async function deleteColumn(parentNoteId: string, type: "label" | "relation", columnName: string) {
|
||||||
|
|||||||
@ -31,8 +31,8 @@ export default function TableView({ note, noteIds, notePath, viewConfig, saveCon
|
|||||||
const contextMenuEvents = useContextMenu(note, parentComponent, tabulatorRef);
|
const contextMenuEvents = useContextMenu(note, parentComponent, tabulatorRef);
|
||||||
const persistenceProps = usePersistence(viewConfig, saveConfig);
|
const persistenceProps = usePersistence(viewConfig, saveConfig);
|
||||||
const rowEditingEvents = useRowTableEditing(tabulatorRef, attributeDetailWidget, notePath);
|
const rowEditingEvents = useRowTableEditing(tabulatorRef, attributeDetailWidget, notePath);
|
||||||
const { newAttributePosition } = useColTableEditing(tabulatorRef, attributeDetailWidget, note);
|
const { newAttributePosition, resetNewAttributePosition } = useColTableEditing(tabulatorRef, attributeDetailWidget, note);
|
||||||
const { columnDefs, rowData, movableRows, hasChildren } = useData(note, noteIds, viewConfig, newAttributePosition);
|
const { columnDefs, rowData, movableRows, hasChildren } = useData(note, noteIds, viewConfig, newAttributePosition, resetNewAttributePosition);
|
||||||
const dataTreeProps = useMemo<Options>(() => {
|
const dataTreeProps = useMemo<Options>(() => {
|
||||||
if (!hasChildren) return {};
|
if (!hasChildren) return {};
|
||||||
return {
|
return {
|
||||||
@ -108,7 +108,7 @@ function usePersistence(initialConfig: TableConfig | null | undefined, saveConfi
|
|||||||
return { persistenceReaderFunc, persistenceWriterFunc };
|
return { persistenceReaderFunc, persistenceWriterFunc };
|
||||||
}
|
}
|
||||||
|
|
||||||
function useData(note: FNote, noteIds: string[], viewConfig: TableConfig | undefined, newAttributePosition: RefObject<number | undefined>) {
|
function useData(note: FNote, noteIds: string[], viewConfig: TableConfig | undefined, newAttributePosition: RefObject<number | undefined>, resetNewAttributePosition: () => void) {
|
||||||
const [ maxDepth ] = useNoteLabelInt(note, "maxNestingDepth") ?? -1;
|
const [ maxDepth ] = useNoteLabelInt(note, "maxNestingDepth") ?? -1;
|
||||||
|
|
||||||
const [ columnDefs, setColumnDefs ] = useState<ColumnDefinition[]>();
|
const [ columnDefs, setColumnDefs ] = useState<ColumnDefinition[]>();
|
||||||
@ -130,6 +130,7 @@ function useData(note: FNote, noteIds: string[], viewConfig: TableConfig | undef
|
|||||||
setColumnDefs(columnDefs);
|
setColumnDefs(columnDefs);
|
||||||
setRowData(rowData);
|
setRowData(rowData);
|
||||||
setHasChildren(hasChildren);
|
setHasChildren(hasChildren);
|
||||||
|
resetNewAttributePosition();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,37 +0,0 @@
|
|||||||
import { Tabulator } from "tabulator-tables";
|
|
||||||
import AttributeDetailWidget from "../../attribute_widgets/attribute_detail";
|
|
||||||
import Component from "../../../components/component";
|
|
||||||
import { CommandListenerData, EventData } from "../../../components/app_context";
|
|
||||||
import attributes from "../../../services/attributes";
|
|
||||||
import FNote from "../../../entities/fnote";
|
|
||||||
import { deleteColumn, renameColumn } from "./bulk_actions";
|
|
||||||
import dialog from "../../../services/dialog";
|
|
||||||
import { t } from "../../../services/i18n";
|
|
||||||
|
|
||||||
export default class TableColumnEditing extends Component {
|
|
||||||
|
|
||||||
private api: Tabulator;
|
|
||||||
private parentNote: FNote;
|
|
||||||
|
|
||||||
private newAttribute?: Attribute;
|
|
||||||
|
|
||||||
constructor($parent: JQuery<HTMLElement>, parentNote: FNote, api: Tabulator) {
|
|
||||||
super();
|
|
||||||
const parentComponent = glob.getComponentByEl($parent[0]);
|
|
||||||
this.api = api;
|
|
||||||
this.parentNote = parentNote;
|
|
||||||
}
|
|
||||||
|
|
||||||
getNewAttributePosition() {
|
|
||||||
return this.newAttributePosition;
|
|
||||||
}
|
|
||||||
|
|
||||||
resetNewAttributePosition() {
|
|
||||||
this.newAttribute = undefined;
|
|
||||||
this.newAttributePosition = undefined;
|
|
||||||
this.existingAttributeToEdit = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,101 +0,0 @@
|
|||||||
import ViewMode, { type ViewModeArgs } from "../view_mode.js";
|
|
||||||
import attributes from "../../../services/attributes.js";
|
|
||||||
import SpacedUpdate from "../../../services/spaced_update.js";
|
|
||||||
import type { EventData } from "../../../components/app_context.js";
|
|
||||||
|
|
||||||
import buildFooter from "./footer.js";
|
|
||||||
import getAttributeDefinitionInformation, { buildRowDefinitions } from "./rows.js";
|
|
||||||
import { AttributeDefinitionInformation, buildColumnDefinitions } from "./columns.js";
|
|
||||||
import { setupContextMenu } from "./context_menu.js";
|
|
||||||
import TableColumnEditing from "./col_editing.js";
|
|
||||||
import TableRowEditing from "./row_editing.js";
|
|
||||||
|
|
||||||
const TPL = /*html*/`
|
|
||||||
<style>
|
|
||||||
|
|
||||||
</style>
|
|
||||||
`;
|
|
||||||
|
|
||||||
export interface StateInfo {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class TableView extends ViewMode<StateInfo> {
|
|
||||||
|
|
||||||
private $root: JQuery<HTMLElement>;
|
|
||||||
private $container: JQuery<HTMLElement>;
|
|
||||||
private spacedUpdate: SpacedUpdate;
|
|
||||||
private api?: Tabulator;
|
|
||||||
private persistentData: StateInfo["tableData"];
|
|
||||||
private colEditing?: TableColumnEditing;
|
|
||||||
private rowEditing?: TableRowEditing;
|
|
||||||
private maxDepth: number = -1;
|
|
||||||
private rowNumberHint: number = 1;
|
|
||||||
|
|
||||||
constructor(args: ViewModeArgs) {
|
|
||||||
super(args, "table");
|
|
||||||
|
|
||||||
this.$root = $(TPL);
|
|
||||||
this.$container = this.$root.find(".table-view-container");
|
|
||||||
this.spacedUpdate = new SpacedUpdate(() => this.onSave(), 5_000);
|
|
||||||
this.persistentData = {};
|
|
||||||
args.$parent.append(this.$root);
|
|
||||||
}
|
|
||||||
|
|
||||||
async renderList() {
|
|
||||||
this.$container.empty();
|
|
||||||
this.renderTable(this.$container[0]);
|
|
||||||
return this.$root;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async initialize(el: HTMLElement, info: AttributeDefinitionInformation[]) {
|
|
||||||
const viewStorage = await this.viewStorage.restore();
|
|
||||||
this.persistentData = viewStorage?.tableData || {};
|
|
||||||
|
|
||||||
this.api = new Tabulator(el, opts);
|
|
||||||
|
|
||||||
this.colEditing = new TableColumnEditing(this.args.$parent, this.args.parentNote, this.api);
|
|
||||||
this.rowEditing = new TableRowEditing(this.api, this.args.parentNotePath!);
|
|
||||||
|
|
||||||
setupContextMenu(this.api, this.parentNote);
|
|
||||||
}
|
|
||||||
|
|
||||||
#manageColumnUpdate() {
|
|
||||||
if (!this.api) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const info = getAttributeDefinitionInformation(this.parentNote);
|
|
||||||
const columnDefs = buildColumnDefinitions({
|
|
||||||
info,
|
|
||||||
movableRows: !!this.api.options.movableRows,
|
|
||||||
existingColumnData: this.persistentData?.columns,
|
|
||||||
rowNumberHint: this.rowNumberHint,
|
|
||||||
position: this.colEditing?.getNewAttributePosition()
|
|
||||||
});
|
|
||||||
this.api.setColumns(columnDefs);
|
|
||||||
this.colEditing?.resetNewAttributePosition();
|
|
||||||
}
|
|
||||||
|
|
||||||
deleteTableColumnCommand(e) { this.colEditing?.deleteTableColumnCommand(e); }
|
|
||||||
|
|
||||||
async #manageRowsUpdate() {
|
|
||||||
if (!this.api) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const info = getAttributeDefinitionInformation(this.parentNote);
|
|
||||||
const { definitions, hasSubtree, rowNumber } = await buildRowDefinitions(this.parentNote, info, this.maxDepth);
|
|
||||||
this.rowNumberHint = rowNumber;
|
|
||||||
|
|
||||||
// Force a refresh if the data tree needs enabling/disabling.
|
|
||||||
if (this.api.options.dataTree !== hasSubtree) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
await this.api.replaceData(definitions);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user