117 lines
3.7 KiB
JavaScript
Raw Normal View History

2020-04-26 09:40:02 +02:00
import CollapsibleWidget from "../collapsible_widget.js";
import treeCache from "../../services/tree_cache.js";
2019-07-21 21:55:48 +02:00
let linkMapContainerIdCtr = 1;
const TPL = `
2019-08-30 20:15:59 +02:00
<div class="link-map-widget">
<div class="link-map-container" style="height: 300px;"></div>
2019-07-21 21:55:48 +02:00
</div>
`;
2020-02-02 21:16:20 +01:00
export default class LinkMapWidget extends CollapsibleWidget {
isEnabled() {
return super.isEnabled() && !this.note.hasLabel('linkMapWidgetDisabled');
}
2020-03-16 22:14:18 +01:00
get widgetTitle() { return "Link map"; }
2019-07-24 22:52:51 +02:00
2020-03-16 22:14:18 +01:00
get help() {
return {
title: "Link map shows incoming and outgoing links from/to the current note.",
url: "https://github.com/zadam/trilium/wiki/Link-map"
};
}
2020-03-16 22:14:18 +01:00
get headerActions() {
const $showFullButton = $("<a>")
2020-11-29 22:32:31 +01:00
.addClass("bx bx-network-chart")
.addClass('widget-header-action')
.attr('title', 'Show full link map');
2019-11-09 17:39:48 +01:00
$showFullButton.on('click', async () => {
2020-04-26 09:40:02 +02:00
const linkMapDialog = await import("../../dialogs/link_map.js");
2019-07-24 22:52:51 +02:00
linkMapDialog.showDialog();
});
2019-08-17 10:45:20 +02:00
return [$showFullButton];
2019-07-21 21:55:48 +02:00
}
decorateWidget() {
this.$body.css("max-height", "400px");
}
async refreshWithNote(note) {
const noteId = this.noteId;
let shown = false;
// avoid executing this expensive operation multiple times when just going through notes (with keyboard especially)
// until the users settles on a note
setTimeout(() => {
if (this.noteId === noteId) {
// there's a problem with centering the rendered link map before it is actually shown on the screen
// that's why we make the whole process lazy and with the help of IntersectionObserver wait until the
// tab is really shown and only then render
const observer = new IntersectionObserver(entries => {
if (!shown && entries[0].isIntersecting) {
shown = true;
this.displayLinkMap(note);
}
}, {
rootMargin: '0px',
threshold: 0.1
});
observer.observe(this.$body[0]);
}
}, 1000);
}
async displayLinkMap(note) {
this.$body.css('opacity', 0);
this.$body.html(TPL);
2019-08-15 10:04:03 +02:00
2019-08-27 20:20:00 +02:00
const $linkMapContainer = this.$body.find('.link-map-container');
$linkMapContainer.attr("id", "link-map-container-" + linkMapContainerIdCtr++);
2019-07-21 21:55:48 +02:00
2020-04-26 09:40:02 +02:00
const LinkMapServiceClass = (await import('../../services/link_map.js')).default;
2019-07-21 21:55:48 +02:00
2020-02-02 20:02:08 +01:00
this.linkMapService = new LinkMapServiceClass(note, $linkMapContainer, {
2019-08-27 22:19:32 +02:00
maxDepth: 1,
2020-02-02 20:02:08 +01:00
zoom: 0.6,
stopCheckerCallback: () => this.noteId !== note.noteId // stop when current note is not what was originally requested
2019-08-27 22:19:32 +02:00
});
2019-07-21 21:55:48 +02:00
2019-08-28 21:15:16 +02:00
await this.linkMapService.render();
this.$body.animate({opacity: 1}, 300);
2019-08-28 21:15:16 +02:00
}
cleanup() {
if (this.linkMapService) {
this.linkMapService.cleanup();
}
2019-07-21 21:55:48 +02:00
}
2019-08-29 23:08:30 +02:00
2020-02-16 19:23:49 +01:00
entitiesReloadedEvent({loadResults}) {
2020-01-29 21:38:58 +01:00
if (loadResults.getAttributes().find(attr => attr.type === 'relation' && (attr.noteId === this.noteId || attr.value === this.noteId))) {
this.noteSwitched();
2019-08-29 23:08:30 +02:00
}
const changedNoteIds = loadResults.getNoteIds();
if (changedNoteIds.length > 0) {
const $linkMapContainer = this.$body.find('.link-map-container');
for (const noteId of changedNoteIds) {
const note = treeCache.notes[noteId];
if (note) {
$linkMapContainer.find(`a[data-note-path="${noteId}"]`).text(note.title);
}
}
}
2019-08-29 23:08:30 +02:00
}
}