chore(react/collections/table): port note relation formatter

This commit is contained in:
Elian Doran 2025-09-09 21:20:52 +03:00
parent 4d57134aa2
commit 3789edf53a
No known key found for this signature in database
2 changed files with 18 additions and 57 deletions

View File

@ -1,11 +1,12 @@
import { NoteFormatter, NoteTitleFormatter, RowNumberFormatter } from "./formatters.js";
import { NoteTitleFormatter, RowNumberFormatter } from "./formatters.js";
import type { CellComponent, ColumnDefinition, EmptyCallback, FormatterParams } from "tabulator-tables";
import { LabelType } from "../../../services/promoted_attribute_definition_parser.js";
import { RelationEditor } from "./relation_editor.js";
import { JSX } from "preact";
import { renderReactWidget } from "../../react/react_utils.jsx";
import NoteTitleWidget from "../../note_title.jsx";
import Icon from "../../react/Icon.jsx";
import { useEffect, useState } from "preact/hooks";
import froca from "../../../services/froca.js";
type ColumnType = LabelType | "relation";
@ -50,7 +51,7 @@ const labelTypeMappings: Record<ColumnType, Partial<ColumnDefinition>> = {
},
relation: {
editor: RelationEditor,
formatter: NoteFormatter
formatter: wrapFormatter(NoteFormatter)
}
};
@ -188,3 +189,17 @@ function wrapFormatter(Component: (opts: FormatterOpts) => JSX.Element): ((cell:
};
}
function NoteFormatter({ cell }: FormatterOpts) {
const noteId = cell.getValue();
const [ note, setNote ] = useState(noteId ? froca.getNoteFromCache(noteId) : null)
useEffect(() => {
if (!noteId || note?.noteId === noteId) return;
froca.getNote(noteId).then(setNote);
}, [ noteId ]);
return <span className={`reference-link ${note?.getColorClass()}`} data-href={`#root/${noteId}`}>
{note && <><Icon icon={note?.getIcon()} />{" "}{note.title}</>}
</span>;
}

View File

@ -1,54 +0,0 @@
import { CellComponent } from "tabulator-tables";
import froca from "../../../services/froca.js";
import FNote from "../../../entities/fnote.js";
/**
* Custom formatter to represent a note, with the icon and note title being rendered.
*
* The value of the cell must be the note ID.
*/
export function NoteFormatter(cell: CellComponent, _formatterParams, onRendered): string {
let noteId = cell.getValue();
if (!noteId) {
return "";
}
function buildLink(note: FNote | undefined) {
if (!note) {
return;
}
const iconClass = note.getIcon();
const title = note.title;
const { $noteRef } = buildNoteLink(noteId, title, iconClass, note.getColorClass());
return $noteRef[0];
}
const cachedNote = froca.getNoteFromCache(noteId);
if (cachedNote) {
// Cache hit, build the link immediately
const el = buildLink(cachedNote);
return el?.outerHTML ?? "";
} else {
// Cache miss, load the note asynchronously
onRendered(async () => {
const note = await froca.getNote(noteId);
if (!note) {
return;
}
const el = buildLink(note);
if (el) {
cell.getElement().appendChild(el);
}
});
return "";
}
}
function buildNoteLink(noteId: string, title: string, iconClass: string, colorClass?: string) {
const $noteRef = $("<span>");
const href = `#root/${noteId}`;
return { $noteRef, href };
}