mirror of
https://github.com/zadam/trilium.git
synced 2025-10-21 07:38:53 +02:00
feat(views/table): basic nested tree support
This commit is contained in:
parent
e30478e5d4
commit
d77a49857b
@ -6,14 +6,15 @@ import SpacedUpdate from "../../../services/spaced_update.js";
|
|||||||
import type { CommandListenerData, EventData } from "../../../components/app_context.js";
|
import type { CommandListenerData, EventData } from "../../../components/app_context.js";
|
||||||
import type { Attribute } from "../../../services/attribute_parser.js";
|
import type { Attribute } from "../../../services/attribute_parser.js";
|
||||||
import note_create, { CreateNoteOpts } from "../../../services/note_create.js";
|
import note_create, { CreateNoteOpts } from "../../../services/note_create.js";
|
||||||
import {Tabulator, SortModule, FormatModule, InteractionModule, EditModule, ResizeColumnsModule, FrozenColumnsModule, PersistenceModule, MoveColumnsModule, MenuModule, MoveRowsModule, ColumnDefinition} from 'tabulator-tables';
|
import {Tabulator, SortModule, FormatModule, InteractionModule, EditModule, ResizeColumnsModule, FrozenColumnsModule, PersistenceModule, MoveColumnsModule, MoveRowsModule, ColumnDefinition, DataTreeModule} from 'tabulator-tables';
|
||||||
import "tabulator-tables/dist/css/tabulator.css";
|
import "tabulator-tables/dist/css/tabulator.css";
|
||||||
import "../../../../src/stylesheets/table.css";
|
import "../../../../src/stylesheets/table.css";
|
||||||
import { canReorderRows, configureReorderingRows } from "./dragging.js";
|
import { canReorderRows, configureReorderingRows } from "./dragging.js";
|
||||||
import buildFooter from "./footer.js";
|
import buildFooter from "./footer.js";
|
||||||
import getAttributeDefinitionInformation, { buildRowDefinitions } from "./rows.js";
|
import getAttributeDefinitionInformation, { buildRowDefinitions, TableData } from "./rows.js";
|
||||||
import { buildColumnDefinitions } from "./columns.js";
|
import { AttributeDefinitionInformation, buildColumnDefinitions } from "./columns.js";
|
||||||
import { setupContextMenu } from "./context_menu.js";
|
import { setupContextMenu } from "./context_menu.js";
|
||||||
|
import { Unwrapped } from "knockout";
|
||||||
|
|
||||||
const TPL = /*html*/`
|
const TPL = /*html*/`
|
||||||
<div class="table-view">
|
<div class="table-view">
|
||||||
@ -111,32 +112,32 @@ export default class TableView extends ViewMode<StateInfo> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async renderTable(el: HTMLElement) {
|
private async renderTable(el: HTMLElement) {
|
||||||
const modules = [ SortModule, FormatModule, InteractionModule, EditModule, ResizeColumnsModule, FrozenColumnsModule, PersistenceModule, MoveColumnsModule, MoveRowsModule ];
|
const info = getAttributeDefinitionInformation(this.parentNote);
|
||||||
|
const modules = [ SortModule, FormatModule, InteractionModule, EditModule, ResizeColumnsModule, FrozenColumnsModule, PersistenceModule, MoveColumnsModule, MoveRowsModule, DataTreeModule ];
|
||||||
for (const module of modules) {
|
for (const module of modules) {
|
||||||
Tabulator.registerModule(module);
|
Tabulator.registerModule(module);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.initialize(el);
|
this.initialize(el, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async initialize(el: HTMLElement) {
|
private async initialize(el: HTMLElement, info: AttributeDefinitionInformation[]) {
|
||||||
const notes = await froca.getNotes(this.args.noteIds);
|
|
||||||
const info = getAttributeDefinitionInformation(this.parentNote);
|
|
||||||
|
|
||||||
const viewStorage = await this.viewStorage.restore();
|
const viewStorage = await this.viewStorage.restore();
|
||||||
this.persistentData = viewStorage?.tableData || {};
|
this.persistentData = viewStorage?.tableData || {};
|
||||||
|
|
||||||
const columnDefs = buildColumnDefinitions(info);
|
const columnDefs = buildColumnDefinitions(info);
|
||||||
const movableRows = canReorderRows(this.parentNote);
|
const { definitions: rowData, hasChildren } = await buildRowDefinitions(this.parentNote, info);
|
||||||
|
const movableRows = canReorderRows(this.parentNote) && !hasChildren;
|
||||||
|
|
||||||
this.api = new Tabulator(el, {
|
this.api = new Tabulator(el, {
|
||||||
layout: "fitDataFill",
|
layout: "fitDataFill",
|
||||||
index: "noteId",
|
index: "noteId",
|
||||||
columns: columnDefs,
|
columns: columnDefs,
|
||||||
data: await buildRowDefinitions(this.parentNote, notes, info),
|
data: rowData,
|
||||||
persistence: true,
|
persistence: true,
|
||||||
movableColumns: true,
|
movableColumns: true,
|
||||||
movableRows,
|
movableRows,
|
||||||
|
dataTree: hasChildren,
|
||||||
footerElement: buildFooter(this.parentNote),
|
footerElement: buildFooter(this.parentNote),
|
||||||
persistenceWriterFunc: (_id, type: string, data: object) => {
|
persistenceWriterFunc: (_id, type: string, data: object) => {
|
||||||
(this.persistentData as Record<string, {}>)[type] = data;
|
(this.persistentData as Record<string, {}>)[type] = data;
|
||||||
@ -255,9 +256,9 @@ export default class TableView extends ViewMode<StateInfo> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const notes = await froca.getNotes(this.args.noteIds);
|
|
||||||
const info = getAttributeDefinitionInformation(this.parentNote);
|
const info = getAttributeDefinitionInformation(this.parentNote);
|
||||||
this.api.replaceData(await buildRowDefinitions(this.parentNote, notes, info));
|
const { definitions } = await buildRowDefinitions(this.parentNote, info);
|
||||||
|
this.api.replaceData(definitions);
|
||||||
|
|
||||||
if (this.noteIdToEdit) {
|
if (this.noteIdToEdit) {
|
||||||
const row = this.api?.getRows().find(r => r.getData().noteId === this.noteIdToEdit);
|
const row = this.api?.getRows().find(r => r.getData().noteId === this.noteIdToEdit);
|
||||||
|
@ -9,10 +9,12 @@ export type TableData = {
|
|||||||
labels: Record<string, boolean | string | null>;
|
labels: Record<string, boolean | string | null>;
|
||||||
relations: Record<string, boolean | string | null>;
|
relations: Record<string, boolean | string | null>;
|
||||||
branchId: string;
|
branchId: string;
|
||||||
|
_children?: TableData[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function buildRowDefinitions(parentNote: FNote, notes: FNote[], infos: AttributeDefinitionInformation[]) {
|
export async function buildRowDefinitions(parentNote: FNote, infos: AttributeDefinitionInformation[]) {
|
||||||
const definitions: TableData[] = [];
|
const definitions: TableData[] = [];
|
||||||
|
let hasChildren = false;
|
||||||
for (const branch of parentNote.getChildBranches()) {
|
for (const branch of parentNote.getChildBranches()) {
|
||||||
const note = await branch.getNote();
|
const note = await branch.getNote();
|
||||||
if (!note) {
|
if (!note) {
|
||||||
@ -28,17 +30,28 @@ export async function buildRowDefinitions(parentNote: FNote, notes: FNote[], inf
|
|||||||
labels[name] = note.getLabelValue(name);
|
labels[name] = note.getLabelValue(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
definitions.push({
|
|
||||||
|
const def: TableData = {
|
||||||
iconClass: note.getIcon(),
|
iconClass: note.getIcon(),
|
||||||
noteId: note.noteId,
|
noteId: note.noteId,
|
||||||
title: note.title,
|
title: note.title,
|
||||||
labels,
|
labels,
|
||||||
relations,
|
relations,
|
||||||
branchId: branch.branchId
|
branchId: branch.branchId,
|
||||||
});
|
}
|
||||||
|
|
||||||
|
if (note.hasChildren()) {
|
||||||
|
def._children = (await buildRowDefinitions(note, infos)).definitions;
|
||||||
|
hasChildren = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
definitions.push(def);
|
||||||
}
|
}
|
||||||
|
|
||||||
return definitions;
|
return {
|
||||||
|
definitions,
|
||||||
|
hasChildren
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function getAttributeDefinitionInformation(parentNote: FNote) {
|
export default function getAttributeDefinitionInformation(parentNote: FNote) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user