mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
cleaned up link map
This commit is contained in:
parent
07e214c564
commit
d4a955a3f5
@ -1,36 +0,0 @@
|
|||||||
import utils from "../services/utils.js";
|
|
||||||
import LinkMapService from "../services/link_map.js";
|
|
||||||
import appContext from "../services/app_context.js";
|
|
||||||
|
|
||||||
const $linkMapContainer = $("#link-map-container");
|
|
||||||
|
|
||||||
const $dialog = $("#link-map-dialog");
|
|
||||||
const $maxNotesInput = $("#link-map-max-notes");
|
|
||||||
|
|
||||||
let linkMapService;
|
|
||||||
|
|
||||||
function getOptions() {
|
|
||||||
return {
|
|
||||||
maxNotes: $maxNotesInput.val()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function showDialog() {
|
|
||||||
// set default settings
|
|
||||||
$maxNotesInput.val(20);
|
|
||||||
|
|
||||||
$linkMapContainer.css("height", $("body").height() - 150);
|
|
||||||
|
|
||||||
$linkMapContainer.empty();
|
|
||||||
|
|
||||||
utils.openDialog($dialog);
|
|
||||||
}
|
|
||||||
|
|
||||||
$dialog.on('shown.bs.modal', () => {
|
|
||||||
const note = appContext.tabManager.getActiveContextNote();
|
|
||||||
|
|
||||||
linkMapService = new LinkMapService(note, $linkMapContainer, getOptions());
|
|
||||||
linkMapService.render();
|
|
||||||
});
|
|
||||||
|
|
||||||
$maxNotesInput.on("input", () => linkMapService.loadNotesAndRelations(getOptions()));
|
|
@ -35,7 +35,6 @@ import ClosePaneButton from "../widgets/buttons/close_pane_button.js";
|
|||||||
import BasicPropertiesWidget from "../widgets/section_widgets/basic_properties.js";
|
import BasicPropertiesWidget from "../widgets/section_widgets/basic_properties.js";
|
||||||
import NoteInfoWidget from "../widgets/section_widgets/note_info_widget.js";
|
import NoteInfoWidget from "../widgets/section_widgets/note_info_widget.js";
|
||||||
import BookPropertiesWidget from "../widgets/section_widgets/book_properties.js";
|
import BookPropertiesWidget from "../widgets/section_widgets/book_properties.js";
|
||||||
import ShowNoteSourceButton from "../widgets/buttons/show_note_source.js";
|
|
||||||
import LinkMapWidget from "../widgets/section_widgets/link_map.js";
|
import LinkMapWidget from "../widgets/section_widgets/link_map.js";
|
||||||
import NotePathsWidget from "../widgets/section_widgets/note_paths.js";
|
import NotePathsWidget from "../widgets/section_widgets/note_paths.js";
|
||||||
import SimilarNotesWidget from "../widgets/section_widgets/similar_notes.js";
|
import SimilarNotesWidget from "../widgets/section_widgets/similar_notes.js";
|
||||||
|
@ -33,17 +33,6 @@ const RELATION_MAP = {
|
|||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
const LINK_MAP = {
|
|
||||||
js: [
|
|
||||||
"libraries/jsplumb.js",
|
|
||||||
"libraries/panzoom.js",
|
|
||||||
"libraries/springy.js"
|
|
||||||
],
|
|
||||||
css: [
|
|
||||||
"stylesheets/link_map.css"
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
const PRINT_THIS = {js: ["libraries/printThis.js"]};
|
const PRINT_THIS = {js: ["libraries/printThis.js"]};
|
||||||
|
|
||||||
const CALENDAR_WIDGET = {css: ["stylesheets/calendar.css"]};
|
const CALENDAR_WIDGET = {css: ["stylesheets/calendar.css"]};
|
||||||
@ -106,7 +95,6 @@ export default {
|
|||||||
ESLINT,
|
ESLINT,
|
||||||
COMMONMARK,
|
COMMONMARK,
|
||||||
RELATION_MAP,
|
RELATION_MAP,
|
||||||
LINK_MAP,
|
|
||||||
PRINT_THIS,
|
PRINT_THIS,
|
||||||
CALENDAR_WIDGET,
|
CALENDAR_WIDGET,
|
||||||
KATEX,
|
KATEX,
|
||||||
|
@ -22,10 +22,6 @@ export default class RootCommandExecutor extends Component {
|
|||||||
import("../dialogs/note_source.js").then(d => d.showDialog());
|
import("../dialogs/note_source.js").then(d => d.showDialog());
|
||||||
}
|
}
|
||||||
|
|
||||||
showLinkMapCommand() {
|
|
||||||
import("../dialogs/link_map.js").then(d => d.showDialog());
|
|
||||||
}
|
|
||||||
|
|
||||||
pasteMarkdownIntoTextCommand() {
|
pasteMarkdownIntoTextCommand() {
|
||||||
import("../dialogs/markdown_import.js").then(d => d.importMarkdownInline());
|
import("../dialogs/markdown_import.js").then(d => d.importMarkdownInline());
|
||||||
}
|
}
|
||||||
|
@ -1,115 +0,0 @@
|
|||||||
import CollapsibleWidget from "../collapsible_widget.js";
|
|
||||||
import froca from "../../services/froca.js";
|
|
||||||
|
|
||||||
let linkMapContainerIdCtr = 1;
|
|
||||||
|
|
||||||
const TPL = `
|
|
||||||
<div class="link-map-widget">
|
|
||||||
<div class="link-map-container" style="height: 300px;"></div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
export default class LinkMapWidget extends CollapsibleWidget {
|
|
||||||
isEnabled() {
|
|
||||||
return super.isEnabled() && !this.note.hasLabel('linkMapWidgetDisabled');
|
|
||||||
}
|
|
||||||
|
|
||||||
get widgetTitle() { return "Link map"; }
|
|
||||||
|
|
||||||
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"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
get headerActions() {
|
|
||||||
const $showFullButton = $("<a>")
|
|
||||||
.addClass("bx bx-network-chart")
|
|
||||||
.addClass('widget-header-action')
|
|
||||||
.attr('title', 'Show full link map');
|
|
||||||
|
|
||||||
$showFullButton.on('click', async () => {
|
|
||||||
const linkMapDialog = await import("../../dialogs/link_map.js");
|
|
||||||
linkMapDialog.showDialog();
|
|
||||||
});
|
|
||||||
|
|
||||||
return [$showFullButton];
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
const $linkMapContainer = this.$body.find('.link-map-container');
|
|
||||||
$linkMapContainer.attr("id", "link-map-container-" + linkMapContainerIdCtr++);
|
|
||||||
|
|
||||||
const LinkMapServiceClass = (await import('../../services/link_map.js')).default;
|
|
||||||
|
|
||||||
this.linkMapService = new LinkMapServiceClass(note, $linkMapContainer, {
|
|
||||||
maxDepth: 1,
|
|
||||||
zoom: 0.6
|
|
||||||
});
|
|
||||||
|
|
||||||
await this.linkMapService.render();
|
|
||||||
|
|
||||||
this.$body.animate({opacity: 1}, 300);
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup() {
|
|
||||||
if (this.linkMapService) {
|
|
||||||
this.linkMapService.cleanup();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
entitiesReloadedEvent({loadResults}) {
|
|
||||||
if (loadResults.getAttributes().find(attr => attr.type === 'relation' && (attr.noteId === this.noteId || attr.value === this.noteId))) {
|
|
||||||
this.noteSwitched();
|
|
||||||
}
|
|
||||||
|
|
||||||
const changedNoteIds = loadResults.getNoteIds();
|
|
||||||
|
|
||||||
if (changedNoteIds.length > 0) {
|
|
||||||
const $linkMapContainer = this.$body.find('.link-map-container');
|
|
||||||
|
|
||||||
for (const noteId of changedNoteIds) {
|
|
||||||
const note = froca.notes[noteId];
|
|
||||||
|
|
||||||
if (note) {
|
|
||||||
$linkMapContainer.find(`a[data-note-path="${noteId}"]`).text(note.title);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,66 +0,0 @@
|
|||||||
.link-map-container {
|
|
||||||
position: relative;
|
|
||||||
outline: none; /* remove dotted outline on click */
|
|
||||||
}
|
|
||||||
|
|
||||||
.link-map-container .note-box {
|
|
||||||
padding: 0px 8px 8px 8px;
|
|
||||||
position: absolute !important;
|
|
||||||
background-color: var(--main-background-color);
|
|
||||||
color: var(--main-text-color);
|
|
||||||
z-index: 4;
|
|
||||||
border: 1px solid #666;
|
|
||||||
border-radius: 8px;
|
|
||||||
opacity: 0.8;
|
|
||||||
font-size: 11px;
|
|
||||||
width: auto;
|
|
||||||
min-width: 120px;
|
|
||||||
max-width: 250px;
|
|
||||||
overflow: hidden;
|
|
||||||
white-space: nowrap;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
|
|
||||||
.link-map-container .note-box:hover {
|
|
||||||
background-color: var(--more-accented-background-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.link-map-container .note-box .title {
|
|
||||||
font-size: larger;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.link-map-active-note {
|
|
||||||
background-color: var(--accented-background-color) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.link-map-container .jsplumb-connection-hover path {
|
|
||||||
stroke-width: 2 !important;
|
|
||||||
stroke: var(--main-text-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.link-map-widget {
|
|
||||||
outline: none;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.link-map-widget .note-box .title {
|
|
||||||
font-size: 19px !important;
|
|
||||||
font-weight: 600
|
|
||||||
}
|
|
||||||
|
|
||||||
#link-map-dialog .note-box .bx {
|
|
||||||
font-size: 24px !important;
|
|
||||||
position: relative;
|
|
||||||
top: 6px;
|
|
||||||
display: inline-block;
|
|
||||||
margin-right: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.link-map-widget .note-box .bx {
|
|
||||||
font-size: 30px !important;
|
|
||||||
position: relative;
|
|
||||||
top: 6px;
|
|
||||||
display: inline-block;
|
|
||||||
margin-right: 5px;
|
|
||||||
}
|
|
@ -33,7 +33,6 @@
|
|||||||
<%- include('dialogs/prompt.ejs') %>
|
<%- include('dialogs/prompt.ejs') %>
|
||||||
<%- include('dialogs/confirm.ejs') %>
|
<%- include('dialogs/confirm.ejs') %>
|
||||||
<%- include('dialogs/help.ejs') %>
|
<%- include('dialogs/help.ejs') %>
|
||||||
<%- include('dialogs/link_map.ejs') %>
|
|
||||||
<%- include('dialogs/clone_to.ejs') %>
|
<%- include('dialogs/clone_to.ejs') %>
|
||||||
<%- include('dialogs/move_to.ejs') %>
|
<%- include('dialogs/move_to.ejs') %>
|
||||||
<%- include('dialogs/backend_log.ejs') %>
|
<%- include('dialogs/backend_log.ejs') %>
|
||||||
|
@ -1,32 +0,0 @@
|
|||||||
<div id="link-map-dialog" class="modal fade mx-auto" tabindex="-1" role="dialog">
|
|
||||||
<div class="modal-dialog modal-xl" style="max-width: 90%;" role="document">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<h5 class="modal-title" style="width: auto;">Link map</h5>
|
|
||||||
|
|
||||||
<div style="vertical-align: middle;">
|
|
||||||
<div style="display: inline-block; position: relative; top: -3px;">
|
|
||||||
<label for="link-map-max-notes" title="Max number of displayed notes">
|
|
||||||
<strong>max notes:</strong>
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<input id="link-map-max-notes" type="number" value="20" min="5" max="1000" step="5"
|
|
||||||
class="form-control form-control-sm"
|
|
||||||
style="width: 80px; display: inline-block; text-align: right;"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div style="display: inline-block;">
|
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close" style="margin-left: 0;">
|
|
||||||
<span aria-hidden="true">×</span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button class="help-button" type="button" data-help-page="Link-map" title="Help on Link map">?</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="modal-body" style="outline: none; overflow: hidden; height: 85vh;">
|
|
||||||
<div id="link-map-container" class="link-map-container"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
Loading…
x
Reference in New Issue
Block a user