mirror of
https://github.com/zadam/trilium.git
synced 2025-06-06 18:08:33 +02:00
ancillary type widget
This commit is contained in:
parent
b1e2b5ba8e
commit
520ffecd36
@ -146,8 +146,7 @@ class BNoteAncillary extends AbstractBeccaEntity {
|
||||
isProtected: !!this.isProtected,
|
||||
contentCheckSum: this.contentCheckSum,
|
||||
isDeleted: false,
|
||||
utcDateModified: this.utcDateModified,
|
||||
content: this.content,
|
||||
utcDateModified: this.utcDateModified
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -166,14 +166,12 @@ class BNoteRevision extends AbstractBeccaEntity {
|
||||
utcDateLastEdited: this.utcDateLastEdited,
|
||||
utcDateCreated: this.utcDateCreated,
|
||||
utcDateModified: this.utcDateModified,
|
||||
content: this.content,
|
||||
contentLength: this.contentLength
|
||||
};
|
||||
}
|
||||
|
||||
getPojoToSave() {
|
||||
const pojo = this.getPojo();
|
||||
delete pojo.content; // not getting persisted
|
||||
delete pojo.contentLength; // not getting persisted
|
||||
|
||||
if (pojo.isProtected) {
|
||||
|
@ -117,11 +117,19 @@ export default class RootCommandExecutor extends Component {
|
||||
});
|
||||
}
|
||||
|
||||
async showNoteSourceEvent() {
|
||||
async showNoteSourceCommand() {
|
||||
const notePath = appContext.tabManager.getActiveContextNotePath();
|
||||
|
||||
if (notePath) {
|
||||
await appContext.tabManager.openContextWithNote(notePath, { activate: true, viewMode: 'source' });
|
||||
}
|
||||
}
|
||||
|
||||
async showNoteAncillariesCommand() {
|
||||
const notePath = appContext.tabManager.getActiveContextNotePath();
|
||||
|
||||
if (notePath) {
|
||||
await appContext.tabManager.openContextWithNote(notePath, { activate: true, viewMode: 'ancillaries' });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ const TPL = `
|
||||
<a data-trigger-command="renderActiveNote" class="dropdown-item render-note-button"><kbd data-command="renderActiveNote"></kbd> Re-render note</a>
|
||||
<a data-trigger-command="findInText" class="dropdown-item find-in-text-button">Search in note <kbd data-command="findInText"></a>
|
||||
<a data-trigger-command="showNoteSource" class="dropdown-item show-source-button"><kbd data-command="showNoteSource"></kbd> Note source</a>
|
||||
<a data-trigger-command="showNoteAncillaries" class="dropdown-item show-source-button"><kbd data-command="showNoteAncillaries"></kbd> Note ancillaries</a>
|
||||
<a data-trigger-command="openNoteExternally" class="dropdown-item open-note-externally-button"><kbd data-command="openNoteExternally"></kbd> Open note externally</a>
|
||||
<a class="dropdown-item import-files-button">Import files</a>
|
||||
<a class="dropdown-item export-note-button">Export note</a>
|
||||
|
@ -12,7 +12,8 @@ export default class MermaidExportButton extends NoteContextAwareWidget {
|
||||
isEnabled() {
|
||||
return super.isEnabled()
|
||||
&& this.note?.type === 'mermaid'
|
||||
&& this.note.isContentAvailable();
|
||||
&& this.note.isContentAvailable()
|
||||
&& this.noteContext?.viewScope.viewMode === 'default';
|
||||
}
|
||||
|
||||
doRender() {
|
||||
|
@ -36,7 +36,8 @@ export default class MermaidWidget extends NoteContextAwareWidget {
|
||||
isEnabled() {
|
||||
return super.isEnabled()
|
||||
&& this.note?.type === 'mermaid'
|
||||
&& this.note.isContentAvailable();
|
||||
&& this.note.isContentAvailable()
|
||||
&& this.noteContext?.viewScope.viewMode === 'default';
|
||||
}
|
||||
|
||||
doRender() {
|
||||
|
@ -27,6 +27,7 @@ import NoteMapTypeWidget from "./type_widgets/note_map.js";
|
||||
import WebViewTypeWidget from "./type_widgets/web_view.js";
|
||||
import DocTypeWidget from "./type_widgets/doc.js";
|
||||
import ContentWidgetTypeWidget from "./type_widgets/content_widget.js";
|
||||
import AncillariesTypeWidget from "./type_widgets/ancillaries.js";
|
||||
|
||||
const TPL = `
|
||||
<div class="note-detail">
|
||||
@ -61,7 +62,8 @@ const typeWidgetClasses = {
|
||||
'noteMap': NoteMapTypeWidget,
|
||||
'webView': WebViewTypeWidget,
|
||||
'doc': DocTypeWidget,
|
||||
'contentWidget': ContentWidgetTypeWidget
|
||||
'contentWidget': ContentWidgetTypeWidget,
|
||||
'ancillaries': AncillariesTypeWidget
|
||||
};
|
||||
|
||||
export default class NoteDetailWidget extends NoteContextAwareWidget {
|
||||
@ -189,6 +191,8 @@ export default class NoteDetailWidget extends NoteContextAwareWidget {
|
||||
|
||||
if (type === 'text' && this.noteContext.viewScope.viewMode === 'source') {
|
||||
type = 'readOnlyCode';
|
||||
} else if (this.noteContext.viewScope.viewMode === 'ancillaries') {
|
||||
type = 'ancillaries';
|
||||
} else if (type === 'text' && await this.noteContext.isReadOnly()) {
|
||||
type = 'readOnlyText';
|
||||
} else if ((type === 'code' || type === 'mermaid') && await this.noteContext.isReadOnly()) {
|
||||
|
@ -460,7 +460,9 @@ export default class TabRowWidget extends BasicWidget {
|
||||
}
|
||||
|
||||
updateTitle($tab, title) {
|
||||
$tab.find('.note-tab-title').text(title);
|
||||
$tab.attr("title", title)
|
||||
$tab.find('.note-tab-title')
|
||||
.text(title);
|
||||
}
|
||||
|
||||
getTabById(ntxId) {
|
||||
|
79
src/public/app/widgets/type_widgets/ancillaries.js
Normal file
79
src/public/app/widgets/type_widgets/ancillaries.js
Normal file
@ -0,0 +1,79 @@
|
||||
import TypeWidget from "./type_widget.js";
|
||||
import server from "../../services/server.js";
|
||||
|
||||
const TPL = `
|
||||
<div class="note-ancillaries note-detail-printable">
|
||||
<style>
|
||||
.note-ancillaries {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.ancillary-content {
|
||||
max-height: 400px;
|
||||
background: var(--accented-background-color);
|
||||
padding: 10px;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.ancillary-details th {
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="alert alert-info" style="margin: 10px 0 10px 0; padding: 20px;">
|
||||
Note ancillaries are pieces of data attached to a given note, providing ancillary support.
|
||||
This view is useful for diagnostics.
|
||||
</div>
|
||||
|
||||
<div class="note-ancillary-list"></div>
|
||||
</div>`;
|
||||
|
||||
export default class AncillariesTypeWidget extends TypeWidget {
|
||||
static getType() { return "ancillaries"; }
|
||||
|
||||
doRender() {
|
||||
this.$widget = $(TPL);
|
||||
this.$list = this.$widget.find('.note-ancillary-list');
|
||||
|
||||
super.doRender();
|
||||
}
|
||||
|
||||
async doRefresh(note) {
|
||||
this.$list.empty();
|
||||
|
||||
const ancillaries = await server.get(`notes/${this.noteId}/ancillaries?includeContent=true`);
|
||||
|
||||
if (ancillaries.length === 0) {
|
||||
this.$list.html("<strong>This note has no ancillaries.</strong>");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (const ancillary of ancillaries) {
|
||||
this.$list.append(
|
||||
$('<div class="note-ancillary-wrapper">')
|
||||
.append(
|
||||
$('<h4>').append($('<span class="ancillary-name">').text(ancillary.name))
|
||||
)
|
||||
.append(
|
||||
$('<table class="ancillary-details">')
|
||||
.append(
|
||||
$('<tr>')
|
||||
.append($('<th>').text('Length:'))
|
||||
.append($('<td>').text(ancillary.contentLength))
|
||||
.append($('<th>').text('MIME:'))
|
||||
.append($('<td>').text(ancillary.mime))
|
||||
.append($('<th>').text('Date modified:'))
|
||||
.append($('<td>').text(ancillary.utcDateModified))
|
||||
)
|
||||
)
|
||||
.append(
|
||||
$('<pre class="ancillary-content">')
|
||||
.text(ancillary.content)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
@ -127,6 +127,36 @@ function setNoteTypeMime(req) {
|
||||
note.save();
|
||||
}
|
||||
|
||||
function getNoteAncillaries(req) {
|
||||
const includeContent = req.query.includeContent === 'true';
|
||||
const {noteId} = req.params;
|
||||
|
||||
const note = becca.getNote(noteId);
|
||||
|
||||
if (!note) {
|
||||
throw new NotFoundError(`Note '${noteId}' doesn't exist.`);
|
||||
}
|
||||
|
||||
const noteAncillaries = note.getNoteAncillaries();
|
||||
|
||||
return noteAncillaries.map(ancillary => {
|
||||
const pojo = ancillary.getPojo();
|
||||
|
||||
if (includeContent && utils.isStringNote(null, ancillary.mime)) {
|
||||
pojo.content = ancillary.getContent()?.toString();
|
||||
pojo.contentLength = pojo.content.length;
|
||||
|
||||
const MAX_ANCILLARY_LENGTH = 1_000_000;
|
||||
|
||||
if (pojo.content.length > MAX_ANCILLARY_LENGTH) {
|
||||
pojo.content = pojo.content.substring(0, MAX_ANCILLARY_LENGTH);
|
||||
}
|
||||
}
|
||||
|
||||
return pojo;
|
||||
});
|
||||
}
|
||||
|
||||
function saveNoteAncillary(req) {
|
||||
const {noteId, name} = req.params;
|
||||
const {mime, content} = req.body;
|
||||
@ -354,5 +384,6 @@ module.exports = {
|
||||
getDeleteNotesPreview,
|
||||
uploadModifiedFile,
|
||||
forceSaveNoteRevision,
|
||||
getNoteAncillaries,
|
||||
saveNoteAncillary
|
||||
};
|
||||
|
@ -126,6 +126,7 @@ function register(app) {
|
||||
apiRoute(PUT, '/api/notes/:noteId/sort-children', notesApiRoute.sortChildNotes);
|
||||
apiRoute(PUT, '/api/notes/:noteId/protect/:isProtected', notesApiRoute.protectNote);
|
||||
apiRoute(PUT, '/api/notes/:noteId/type', notesApiRoute.setNoteTypeMime);
|
||||
apiRoute(GET, '/api/notes/:noteId/ancillaries', notesApiRoute.getNoteAncillaries);
|
||||
apiRoute(PUT, '/api/notes/:noteId/ancillaries/:name', notesApiRoute.saveNoteAncillary);
|
||||
apiRoute(GET, '/api/notes/:noteId/revisions', noteRevisionsApiRoute.getNoteRevisions);
|
||||
apiRoute(DELETE, '/api/notes/:noteId/revisions', noteRevisionsApiRoute.eraseAllNoteRevisions);
|
||||
|
Loading…
x
Reference in New Issue
Block a user