diff --git a/apps/client/src/widgets/collections/table/columns.tsx b/apps/client/src/widgets/collections/table/columns.tsx index 8a6e319af..6646d643e 100644 --- a/apps/client/src/widgets/collections/table/columns.tsx +++ b/apps/client/src/widgets/collections/table/columns.tsx @@ -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> = { }, 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 + {note && <>{" "}{note.title}} + ; +} + diff --git a/apps/client/src/widgets/collections/table/formatters.ts b/apps/client/src/widgets/collections/table/formatters.ts deleted file mode 100644 index 88a7b2cb1..000000000 --- a/apps/client/src/widgets/collections/table/formatters.ts +++ /dev/null @@ -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 = $(""); - const href = `#root/${noteId}`; - return { $noteRef, href }; -}