mirror of
https://github.com/zadam/trilium.git
synced 2025-11-03 04:59:04 +01:00
99 lines
4.4 KiB
TypeScript
99 lines
4.4 KiB
TypeScript
import { useCallback, useContext, useEffect, useRef, useState } from "preact/hooks";
|
|
import { ViewModeProps } from "../interface";
|
|
import { buildColumnDefinitions } from "./columns";
|
|
import getAttributeDefinitionInformation, { buildRowDefinitions, TableData } from "./rows";
|
|
import { useNoteLabelInt, useSpacedUpdate } from "../../react/hooks";
|
|
import { canReorderRows } from "../../view_widgets/table_view/dragging";
|
|
import Tabulator from "./tabulator";
|
|
import { Tabulator as VanillaTabulator, SortModule, FormatModule, InteractionModule, EditModule, ResizeColumnsModule, FrozenColumnsModule, PersistenceModule, MoveColumnsModule, MoveRowsModule, ColumnDefinition, DataTreeModule} from 'tabulator-tables';
|
|
import { useContextMenu } from "./context_menu";
|
|
import { ParentComponent } from "../../react/react_utils";
|
|
import FNote from "../../../entities/fnote";
|
|
import { t } from "../../../services/i18n";
|
|
import Button from "../../react/Button";
|
|
import "./index.css";
|
|
|
|
interface TableConfig {
|
|
tableData?: {
|
|
columns?: ColumnDefinition[];
|
|
};
|
|
}
|
|
|
|
export default function TableView({ note, viewConfig, saveConfig }: ViewModeProps<TableConfig>) {
|
|
const [ maxDepth ] = useNoteLabelInt(note, "maxNestingDepth") ?? -1;
|
|
const [ columnDefs, setColumnDefs ] = useState<ColumnDefinition[]>();
|
|
const [ rowData, setRowData ] = useState<TableData[]>();
|
|
const tabulatorRef = useRef<VanillaTabulator>(null);
|
|
const parentComponent = useContext(ParentComponent);
|
|
|
|
useEffect(() => {
|
|
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);
|
|
});
|
|
}, [ note ]);
|
|
|
|
const contextMenuEvents = useContextMenu(note, parentComponent, tabulatorRef);
|
|
const persistenceProps = usePersistence(viewConfig, saveConfig);
|
|
console.log("Render with viewconfig", viewConfig);
|
|
|
|
return (
|
|
<div className="table-view">
|
|
{viewConfig && columnDefs && (
|
|
<>
|
|
<Tabulator
|
|
tabulatorRef={tabulatorRef}
|
|
className="table-view-container"
|
|
columns={columnDefs}
|
|
data={rowData}
|
|
modules={[ SortModule, FormatModule, InteractionModule, EditModule, ResizeColumnsModule, FrozenColumnsModule, PersistenceModule, MoveColumnsModule, MoveRowsModule, DataTreeModule ]}
|
|
footerElement={<TableFooter note={note} />}
|
|
{...contextMenuEvents}
|
|
persistence {...persistenceProps}
|
|
/>
|
|
<TableFooter note={note} />
|
|
</>
|
|
)}
|
|
</div>
|
|
)
|
|
}
|
|
|
|
function TableFooter({ note }: { note: FNote }) {
|
|
return (note.type !== "search" &&
|
|
<div className="tabulator-footer">
|
|
<div className="tabulator-footer-contents">
|
|
<Button triggerCommand="addNewRow" icon="bx bx-plus" text={t("table_view.new-row")} />
|
|
{" "}
|
|
<Button triggerCommand="addNewTableColumn" icon="bx bx-carousel" text={t("table_view.new-column")} />
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
function usePersistence(initialConfig: TableConfig | null | undefined, saveConfig: (newConfig: TableConfig) => void) {
|
|
const config = useRef<TableConfig | null | undefined>(initialConfig);
|
|
const spacedUpdate = useSpacedUpdate(() => {
|
|
if (config.current) {
|
|
saveConfig(config.current);
|
|
}
|
|
}, 5_000);
|
|
const persistenceWriterFunc = useCallback((_id, type: string, data: object) => {
|
|
if (!config.current) config.current = {};
|
|
if (!config.current.tableData) config.current.tableData = {};
|
|
(config.current.tableData as Record<string, {}>)[type] = data;
|
|
spacedUpdate.scheduleUpdate();
|
|
}, []);
|
|
const persistenceReaderFunc = useCallback((_id, type: string) => {
|
|
return config.current?.tableData?.[type];
|
|
}, []);
|
|
return { persistenceReaderFunc, persistenceWriterFunc };
|
|
}
|