diff --git a/src/public/app/widgets/floating_buttons/zpetne_odkazy.js b/src/public/app/widgets/floating_buttons/zpetne_odkazy.ts similarity index 82% rename from src/public/app/widgets/floating_buttons/zpetne_odkazy.js rename to src/public/app/widgets/floating_buttons/zpetne_odkazy.ts index 5f4bcf3b3..8f19b37d3 100644 --- a/src/public/app/widgets/floating_buttons/zpetne_odkazy.js +++ b/src/public/app/widgets/floating_buttons/zpetne_odkazy.ts @@ -7,6 +7,7 @@ import NoteContextAwareWidget from "../note_context_aware_widget.js"; import linkService from "../../services/link.js"; import server from "../../services/server.js"; import froca from "../../services/froca.js"; +import type FNote from "../../entities/fnote.js"; const TPL = ` + `; +// TODO: Deduplicate with server +interface Backlink { + noteId: string; + relationName?: string; + excerpts?: string[]; +} + export default class BacklinksWidget extends NoteContextAwareWidget { + + private $count!: JQuery; + private $items!: JQuery; + private $ticker!: JQuery; + doRender() { this.$widget = $(TPL); this.$count = this.$widget.find(".backlinks-count"); @@ -73,7 +86,7 @@ export default class BacklinksWidget extends NoteContextAwareWidget { this.$count.on("click", () => { this.$items.toggle(); - this.$items.css("max-height", $(window).height() - this.$items.offset().top - 10); + this.$items.css("max-height", ($(window).height() ?? 0) - (this.$items.offset()?.top ?? 0) - 10); if (this.$items.is(":visible")) { this.renderBacklinks(); @@ -83,7 +96,7 @@ export default class BacklinksWidget extends NoteContextAwareWidget { this.contentSized(); } - async refreshWithNote(note) { + async refreshWithNote(note: FNote) { this.clearItems(); if (this.noteContext?.viewScope?.viewMode !== "default") { @@ -92,7 +105,8 @@ export default class BacklinksWidget extends NoteContextAwareWidget { } // can't use froca since that would count only relations from loaded notes - const resp = await server.get(`note-map/${this.noteId}/backlink-count`); + // TODO: Deduplicate response type + const resp = await server.get<{ count: number }>(`note-map/${this.noteId}/backlink-count`); if (!resp || !resp.count) { this.toggle(false); @@ -106,7 +120,7 @@ export default class BacklinksWidget extends NoteContextAwareWidget { ); } - toggle(show) { + toggle(show: boolean) { this.$widget.toggleClass("hidden-no-content", !show); } @@ -121,7 +135,7 @@ export default class BacklinksWidget extends NoteContextAwareWidget { this.$items.empty(); - const backlinks = await server.get(`note-map/${this.noteId}/backlinks`); + const backlinks = await server.get(`note-map/${this.noteId}/backlinks`); if (!backlinks.length) { return; @@ -143,7 +157,7 @@ export default class BacklinksWidget extends NoteContextAwareWidget { if (backlink.relationName) { $item.append($("

").text(`${t("zpetne_odkazy.relation")}: ${backlink.relationName}`)); } else { - $item.append(...backlink.excerpts); + $item.append(...backlink.excerpts ?? []); } this.$items.append($item); diff --git a/src/routes/api/note_map.ts b/src/routes/api/note_map.ts index b08c03d1f..684227009 100644 --- a/src/routes/api/note_map.ts +++ b/src/routes/api/note_map.ts @@ -6,6 +6,12 @@ import type BNote from "../../becca/entities/bnote.js"; import type BAttribute from "../../becca/entities/battribute.js"; import type { Request } from "express"; +interface Backlink { + noteId: string; + relationName?: string; + excerpts?: string[]; +} + function buildDescendantCountMap(noteIdsToCount: string[]) { if (!Array.isArray(noteIdsToCount)) { throw new Error("noteIdsToCount: type error"); @@ -325,7 +331,7 @@ function findExcerpts(sourceNote: BNote, referencedNoteId: string) { return excerpts; } -function getFilteredBacklinks(note: BNote) { +function getFilteredBacklinks(note: BNote): BAttribute[] { return ( note .getTargetRelations() @@ -344,7 +350,7 @@ function getBacklinkCount(req: Request) { }; } -function getBacklinks(req: Request) { +function getBacklinks(req: Request): Backlink[] { const { noteId } = req.params; const note = becca.getNoteOrThrow(noteId);