mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
Merge branch 'stable'
This commit is contained in:
commit
05d2f4fe96
1
db/migrations/0214__fix_root_children_ordering.sql
Normal file
1
db/migrations/0214__fix_root_children_ordering.sql
Normal file
@ -0,0 +1 @@
|
|||||||
|
UPDATE branches SET notePosition = notePosition - 999899999 WHERE parentNoteId = 'root' AND notePosition > 999999999;
|
4
package-lock.json
generated
4
package-lock.json
generated
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "trilium",
|
"name": "trilium",
|
||||||
"version": "0.60.2-beta",
|
"version": "0.60.4",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "trilium",
|
"name": "trilium",
|
||||||
"version": "0.60.2-beta",
|
"version": "0.60.4",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "AGPL-3.0-only",
|
"license": "AGPL-3.0-only",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"name": "trilium",
|
"name": "trilium",
|
||||||
"productName": "Trilium Notes",
|
"productName": "Trilium Notes",
|
||||||
"description": "Trilium Notes",
|
"description": "Trilium Notes",
|
||||||
"version": "0.60.2-beta",
|
"version": "0.60.4",
|
||||||
"license": "AGPL-3.0-only",
|
"license": "AGPL-3.0-only",
|
||||||
"main": "electron.js",
|
"main": "electron.js",
|
||||||
"bin": {
|
"bin": {
|
||||||
|
@ -33,13 +33,7 @@ paths:
|
|||||||
content:
|
content:
|
||||||
application/json; charset=utf-8:
|
application/json; charset=utf-8:
|
||||||
schema:
|
schema:
|
||||||
properties:
|
$ref: '#/components/schemas/NoteWithBranch'
|
||||||
note:
|
|
||||||
$ref: '#/components/schemas/Note'
|
|
||||||
description: Created note
|
|
||||||
branch:
|
|
||||||
$ref: '#/components/schemas/Branch'
|
|
||||||
description: Created branch
|
|
||||||
default:
|
default:
|
||||||
description: unexpected error
|
description: unexpected error
|
||||||
content:
|
content:
|
||||||
@ -291,6 +285,29 @@ paths:
|
|||||||
application/json; charset=utf-8:
|
application/json; charset=utf-8:
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/components/schemas/Error'
|
$ref: '#/components/schemas/Error'
|
||||||
|
/notes/{noteId}/import:
|
||||||
|
parameters:
|
||||||
|
- name: noteId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/EntityId'
|
||||||
|
post:
|
||||||
|
description: Imports ZIP file into a given note.
|
||||||
|
operationId: importZip
|
||||||
|
responses:
|
||||||
|
'201':
|
||||||
|
description: note created
|
||||||
|
content:
|
||||||
|
application/json; charset=utf-8:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/NoteWithBranch'
|
||||||
|
default:
|
||||||
|
description: unexpected error
|
||||||
|
content:
|
||||||
|
application/json; charset=utf-8:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
/notes/{noteId}/note-revision:
|
/notes/{noteId}/note-revision:
|
||||||
parameters:
|
parameters:
|
||||||
- name: noteId
|
- name: noteId
|
||||||
@ -852,6 +869,13 @@ components:
|
|||||||
utcDateModified:
|
utcDateModified:
|
||||||
$ref: '#/components/schemas/UtcDateTime'
|
$ref: '#/components/schemas/UtcDateTime'
|
||||||
readOnly: true
|
readOnly: true
|
||||||
|
NoteWithBranch:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
note:
|
||||||
|
$ref: '#/components/schemas/Note'
|
||||||
|
branch:
|
||||||
|
$ref: '#/components/schemas/Branch'
|
||||||
Attribute:
|
Attribute:
|
||||||
type: object
|
type: object
|
||||||
description: Attribute (Label, Relation) is a key-value record attached to a note.
|
description: Attribute (Label, Relation) is a key-value record attached to a note.
|
||||||
|
@ -8,6 +8,7 @@ const v = require("./validators");
|
|||||||
const searchService = require("../services/search/services/search");
|
const searchService = require("../services/search/services/search");
|
||||||
const SearchContext = require("../services/search/search_context");
|
const SearchContext = require("../services/search/search_context");
|
||||||
const zipExportService = require("../services/export/zip");
|
const zipExportService = require("../services/export/zip");
|
||||||
|
const zipImportService = require("../services/import/zip");
|
||||||
|
|
||||||
function register(router) {
|
function register(router) {
|
||||||
eu.route(router, 'get', '/etapi/notes', (req, res, next) => {
|
eu.route(router, 'get', '/etapi/notes', (req, res, next) => {
|
||||||
@ -141,11 +142,21 @@ function register(router) {
|
|||||||
// (e.g. branchIds are not seen in UI), that we export "note export" instead.
|
// (e.g. branchIds are not seen in UI), that we export "note export" instead.
|
||||||
const branch = note.getParentBranches()[0];
|
const branch = note.getParentBranches()[0];
|
||||||
|
|
||||||
console.log(note.getParentBranches());
|
|
||||||
|
|
||||||
zipExportService.exportToZip(taskContext, branch, format, res);
|
zipExportService.exportToZip(taskContext, branch, format, res);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
eu.route(router, 'post' ,'/etapi/notes/:noteId/import', (req, res, next) => {
|
||||||
|
const note = eu.getAndCheckNote(req.params.noteId);
|
||||||
|
const taskContext = new TaskContext('no-progress-reporting');
|
||||||
|
|
||||||
|
zipImportService.importZip(taskContext, req.body, note).then(importedNote => {
|
||||||
|
res.status(201).json({
|
||||||
|
note: mappers.mapNoteToPojo(importedNote),
|
||||||
|
branch: mappers.mapBranchToPojo(importedNote.getBranches()[0]),
|
||||||
|
});
|
||||||
|
}); // we need better error handling here, async errors won't be properly processed.
|
||||||
|
});
|
||||||
|
|
||||||
eu.route(router, 'post' ,'/etapi/notes/:noteId/note-revision', (req, res, next) => {
|
eu.route(router, 'post' ,'/etapi/notes/:noteId/note-revision', (req, res, next) => {
|
||||||
const note = eu.getAndCheckNote(req.params.noteId);
|
const note = eu.getAndCheckNote(req.params.noteId);
|
||||||
|
|
||||||
|
@ -230,6 +230,15 @@ export default class NoteDetailWidget extends NoteContextAwareWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async runActiveNoteCommand(params) {
|
||||||
|
if (this.isNoteContext(params.ntxId)) {
|
||||||
|
// make sure that script is saved before running it #4028
|
||||||
|
await this.spacedUpdate.updateNowIfNecessary();
|
||||||
|
}
|
||||||
|
|
||||||
|
return await this.parent.triggerCommand('runActiveNote', params);
|
||||||
|
}
|
||||||
|
|
||||||
async printActiveNoteEvent() {
|
async printActiveNoteEvent() {
|
||||||
if (!this.noteContext.isActive()) {
|
if (!this.noteContext.isActive()) {
|
||||||
return;
|
return;
|
||||||
|
@ -93,11 +93,11 @@ export default class NoteIconWidget extends NoteContextAwareWidget {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.$iconCategory = this.$widget.find("select[name='icon-category']");
|
this.$iconCategory = this.$widget.find("select[name='icon-category']");
|
||||||
this.$iconCategory.on('change', () => this.renderFilteredDropdown());
|
this.$iconCategory.on('change', () => this.renderDropdown());
|
||||||
this.$iconCategory.on('click', e => e.stopPropagation());
|
this.$iconCategory.on('click', e => e.stopPropagation());
|
||||||
|
|
||||||
this.$iconSearch = this.$widget.find("input[name='icon-search']");
|
this.$iconSearch = this.$widget.find("input[name='icon-search']");
|
||||||
this.$iconSearch.on('input', () => this.renderFilteredDropdown());
|
this.$iconSearch.on('input', () => this.renderDropdown());
|
||||||
|
|
||||||
this.$notePathList = this.$widget.find(".note-path-list");
|
this.$notePathList = this.$widget.find(".note-path-list");
|
||||||
this.$widget.on('show.bs.dropdown', async () => {
|
this.$widget.on('show.bs.dropdown', async () => {
|
||||||
@ -140,15 +140,9 @@ export default class NoteIconWidget extends NoteContextAwareWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
renderFilteredDropdown() {
|
async renderDropdown() {
|
||||||
const categoryId = parseInt(this.$iconCategory.find('option:selected').val());
|
const iconToCount = await this.getIconToCountMap();
|
||||||
const search = this.$iconSearch.val();
|
const {icons} = (await import('./icon_list.js')).default;
|
||||||
|
|
||||||
this.renderDropdown(categoryId, search);
|
|
||||||
}
|
|
||||||
|
|
||||||
async renderDropdown(categoryId, search) {
|
|
||||||
const iconToCountPromise = this.getIconToCountMap();
|
|
||||||
|
|
||||||
this.$iconList.empty();
|
this.$iconList.empty();
|
||||||
|
|
||||||
@ -164,9 +158,8 @@ export default class NoteIconWidget extends NoteContextAwareWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const {icons} = (await import('./icon_list.js')).default;
|
const categoryId = parseInt(this.$iconCategory.find('option:selected').val());
|
||||||
|
const search = this.$iconSearch.val().trim().toLowerCase();
|
||||||
search = search?.trim()?.toLowerCase();
|
|
||||||
|
|
||||||
const filteredIcons = icons.filter(icon => {
|
const filteredIcons = icons.filter(icon => {
|
||||||
if (categoryId && icon.category_id !== categoryId) {
|
if (categoryId && icon.category_id !== categoryId) {
|
||||||
@ -182,8 +175,6 @@ export default class NoteIconWidget extends NoteContextAwareWidget {
|
|||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
const iconToCount = await iconToCountPromise;
|
|
||||||
|
|
||||||
filteredIcons.sort((a, b) => {
|
filteredIcons.sort((a, b) => {
|
||||||
const countA = iconToCount[a.className] || 0;
|
const countA = iconToCount[a.className] || 0;
|
||||||
const countB = iconToCount[b.className] || 0;
|
const countB = iconToCount[b.className] || 0;
|
||||||
@ -199,9 +190,12 @@ export default class NoteIconWidget extends NoteContextAwareWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getIconToCountMap() {
|
async getIconToCountMap() {
|
||||||
const {iconClassToCountMap} = await server.get('other/icon-usage');
|
if (!this.iconToCountCache) {
|
||||||
|
this.iconToCountCache = server.get('other/icon-usage');
|
||||||
|
setTimeout(() => this.iconToCountCache = null, 20000); // invalidate cache after 20 seconds
|
||||||
|
}
|
||||||
|
|
||||||
return iconClassToCountMap;
|
return (await this.iconToCountCache).iconClassToCountMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderIcon(icon) {
|
renderIcon(icon) {
|
||||||
|
@ -285,6 +285,8 @@ export default class ExcalidrawTypeWidget extends TypeWidget {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const content = {
|
const content = {
|
||||||
|
type: "excalidraw",
|
||||||
|
version: 2,
|
||||||
_meta: "This note has type `canvas`. It uses excalidraw and stores an exported svg alongside.",
|
_meta: "This note has type `canvas`. It uses excalidraw and stores an exported svg alongside.",
|
||||||
elements, // excalidraw
|
elements, // excalidraw
|
||||||
appState, // excalidraw
|
appState, // excalidraw
|
||||||
|
@ -185,14 +185,8 @@ export default class EditableTextTypeWidget extends AbstractTextTypeWidget {
|
|||||||
async doRefresh(note) {
|
async doRefresh(note) {
|
||||||
const noteComplement = await froca.getNoteComplement(note.noteId);
|
const noteComplement = await froca.getNoteComplement(note.noteId);
|
||||||
|
|
||||||
await this.spacedUpdate.allowUpdateWithoutChange(() => {
|
await this.spacedUpdate.allowUpdateWithoutChange(() =>
|
||||||
// https://github.com/zadam/trilium/issues/3914
|
this.watchdog.editor.setData(noteComplement.content || ""));
|
||||||
// todo: quite hacky, but it works. remove it if ckeditor has fixed it.
|
|
||||||
this.$editor.trigger('focus');
|
|
||||||
this.$editor.trigger('blur')
|
|
||||||
|
|
||||||
this.watchdog.editor.setData(noteComplement.content || "");
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getData() {
|
getData() {
|
||||||
|
@ -4,7 +4,7 @@ const build = require('./build');
|
|||||||
const packageJson = require('../../package');
|
const packageJson = require('../../package');
|
||||||
const {TRILIUM_DATA_DIR} = require('./data_dir');
|
const {TRILIUM_DATA_DIR} = require('./data_dir');
|
||||||
|
|
||||||
const APP_DB_VERSION = 213;
|
const APP_DB_VERSION = 214;
|
||||||
const SYNC_VERSION = 29;
|
const SYNC_VERSION = 29;
|
||||||
const CLIPPER_PROTOCOL_VERSION = "1.0";
|
const CLIPPER_PROTOCOL_VERSION = "1.0";
|
||||||
|
|
||||||
|
@ -1 +1 @@
|
|||||||
module.exports = { buildDate:"2023-06-08T22:46:52+02:00", buildRevision: "6e69cafe5419e8efcc6f652647f9227dbcfa1e18" };
|
module.exports = { buildDate:"2023-06-19T23:26:50+02:00", buildRevision: "5905950c17791ce0eb278e010c2c8b3450fdb447" };
|
||||||
|
@ -26,11 +26,13 @@ const fs = require("fs");
|
|||||||
function getNewNotePosition(parentNote) {
|
function getNewNotePosition(parentNote) {
|
||||||
if (parentNote.isLabelTruthy('newNotesOnTop')) {
|
if (parentNote.isLabelTruthy('newNotesOnTop')) {
|
||||||
const minNotePos = parentNote.getChildBranches()
|
const minNotePos = parentNote.getChildBranches()
|
||||||
|
.filter(branch => branch.noteId !== '_hidden') // has "always last" note position
|
||||||
.reduce((min, note) => Math.min(min, note.notePosition), 0);
|
.reduce((min, note) => Math.min(min, note.notePosition), 0);
|
||||||
|
|
||||||
return minNotePos - 10;
|
return minNotePos - 10;
|
||||||
} else {
|
} else {
|
||||||
const maxNotePos = parentNote.getChildBranches()
|
const maxNotePos = parentNote.getChildBranches()
|
||||||
|
.filter(branch => branch.noteId !== '_hidden') // has "always last" note position
|
||||||
.reduce((max, note) => Math.max(max, note.notePosition), 0);
|
.reduce((max, note) => Math.max(max, note.notePosition), 0);
|
||||||
|
|
||||||
return maxNotePos + 10;
|
return maxNotePos + 10;
|
||||||
|
@ -19,20 +19,22 @@ class NoteFlatTextExp extends Expression {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {BNote} note
|
* @param {BNote} note
|
||||||
* @param {string[]} tokens
|
* @param {string[]} remainingTokens - tokens still needed to be found in the path towards root
|
||||||
* @param {string[]} path
|
* @param {string[]} takenPath - path so far taken towards from candidate note towards the root.
|
||||||
|
* It contains the suffix fragment of the full note path.
|
||||||
*/
|
*/
|
||||||
const searchDownThePath = (note, tokens, path) => {
|
const searchPathTowardsRoot = (note, remainingTokens, takenPath) => {
|
||||||
if (tokens.length === 0) {
|
if (remainingTokens.length === 0) {
|
||||||
const retPath = this.getNotePath(note, path);
|
// we're done, just build the result
|
||||||
|
const resultPath = this.getNotePath(note, takenPath);
|
||||||
|
|
||||||
if (retPath) {
|
if (resultPath) {
|
||||||
const noteId = retPath[retPath.length - 1];
|
const noteId = resultPath[resultPath.length - 1];
|
||||||
|
|
||||||
if (!resultNoteSet.hasNoteId(noteId)) {
|
if (!resultNoteSet.hasNoteId(noteId)) {
|
||||||
// we could get here from multiple paths, the first one wins because the paths
|
// we could get here from multiple paths, the first one wins because the paths
|
||||||
// are sorted by importance
|
// are sorted by importance
|
||||||
executionContext.noteIdToNotePath[noteId] = retPath;
|
executionContext.noteIdToNotePath[noteId] = resultPath;
|
||||||
|
|
||||||
resultNoteSet.add(becca.notes[noteId]);
|
resultNoteSet.add(becca.notes[noteId]);
|
||||||
}
|
}
|
||||||
@ -42,22 +44,23 @@ class NoteFlatTextExp extends Expression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (note.parents.length === 0 || note.noteId === 'root') {
|
if (note.parents.length === 0 || note.noteId === 'root') {
|
||||||
|
// we've reached root, but there are still remaining tokens -> this candidate note produced no result
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const foundAttrTokens = [];
|
const foundAttrTokens = [];
|
||||||
|
|
||||||
for (const token of tokens) {
|
for (const token of remainingTokens) {
|
||||||
if (note.type.includes(token) || note.mime.includes(token)) {
|
if (note.type.includes(token) || note.mime.includes(token)) {
|
||||||
foundAttrTokens.push(token);
|
foundAttrTokens.push(token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const attribute of note.ownedAttributes) {
|
for (const attribute of note.getOwnedAttributes()) {
|
||||||
const normalizedName = utils.normalize(attribute.name);
|
const normalizedName = utils.normalize(attribute.name);
|
||||||
const normalizedValue = utils.normalize(attribute.value);
|
const normalizedValue = utils.normalize(attribute.value);
|
||||||
|
|
||||||
for (const token of tokens) {
|
for (const token of remainingTokens) {
|
||||||
if (normalizedName.includes(token) || normalizedValue.includes(token)) {
|
if (normalizedName.includes(token) || normalizedValue.includes(token)) {
|
||||||
foundAttrTokens.push(token);
|
foundAttrTokens.push(token);
|
||||||
}
|
}
|
||||||
@ -68,19 +71,19 @@ class NoteFlatTextExp extends Expression {
|
|||||||
const title = utils.normalize(beccaService.getNoteTitle(note.noteId, parentNote.noteId));
|
const title = utils.normalize(beccaService.getNoteTitle(note.noteId, parentNote.noteId));
|
||||||
const foundTokens = foundAttrTokens.slice();
|
const foundTokens = foundAttrTokens.slice();
|
||||||
|
|
||||||
for (const token of tokens) {
|
for (const token of remainingTokens) {
|
||||||
if (title.includes(token)) {
|
if (title.includes(token)) {
|
||||||
foundTokens.push(token);
|
foundTokens.push(token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (foundTokens.length > 0) {
|
if (foundTokens.length > 0) {
|
||||||
const remainingTokens = tokens.filter(token => !foundTokens.includes(token));
|
const newRemainingTokens = remainingTokens.filter(token => !foundTokens.includes(token));
|
||||||
|
|
||||||
searchDownThePath(parentNote, remainingTokens, [...path, note.noteId]);
|
searchPathTowardsRoot(parentNote, newRemainingTokens, [note.noteId, ...takenPath]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
searchDownThePath(parentNote, tokens, [...path, note.noteId]);
|
searchPathTowardsRoot(parentNote, remainingTokens, [note.noteId, ...takenPath]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -90,7 +93,7 @@ class NoteFlatTextExp extends Expression {
|
|||||||
for (const note of candidateNotes) {
|
for (const note of candidateNotes) {
|
||||||
// autocomplete should be able to find notes by their noteIds as well (only leafs)
|
// autocomplete should be able to find notes by their noteIds as well (only leafs)
|
||||||
if (this.tokens.length === 1 && note.noteId.toLowerCase() === this.tokens[0]) {
|
if (this.tokens.length === 1 && note.noteId.toLowerCase() === this.tokens[0]) {
|
||||||
searchDownThePath(note, [], []);
|
searchPathTowardsRoot(note, [], [note.noteId]);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,7 +126,7 @@ class NoteFlatTextExp extends Expression {
|
|||||||
if (foundTokens.length > 0) {
|
if (foundTokens.length > 0) {
|
||||||
const remainingTokens = this.tokens.filter(token => !foundTokens.includes(token));
|
const remainingTokens = this.tokens.filter(token => !foundTokens.includes(token));
|
||||||
|
|
||||||
searchDownThePath(parentNote, remainingTokens, [note.noteId]);
|
searchPathTowardsRoot(parentNote, remainingTokens, [note.noteId]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -131,14 +134,22 @@ class NoteFlatTextExp extends Expression {
|
|||||||
return resultNoteSet;
|
return resultNoteSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
getNotePath(note, path) {
|
/**
|
||||||
if (path.length === 0) {
|
* @param {BNote} note
|
||||||
|
* @param {string[]} takenPath
|
||||||
|
* @returns {string[]}
|
||||||
|
*/
|
||||||
|
getNotePath(note, takenPath) {
|
||||||
|
if (takenPath.length === 0) {
|
||||||
|
throw new Error("Path is not expected to be empty.");
|
||||||
|
} else if (takenPath.length === 1 && takenPath[0] === note.noteId) {
|
||||||
return note.getBestNotePath();
|
return note.getBestNotePath();
|
||||||
} else {
|
} else {
|
||||||
const closestNoteId = path[0];
|
// this note is the closest to root containing the last matching token(s), thus completing the requirements
|
||||||
const closestNoteBestNotePath = becca.getNote(closestNoteId).getBestNotePath();
|
// what's in this note's predecessors does not matter, thus we'll choose the best note path
|
||||||
|
const topMostMatchingTokenNotePath = becca.getNote(takenPath[0]).getBestNotePath();
|
||||||
|
|
||||||
return [...closestNoteBestNotePath, ...path.slice(1)];
|
return [...topMostMatchingTokenNotePath, ...takenPath.slice(1)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,6 @@ const becca = require('../../../becca/becca');
|
|||||||
const beccaService = require('../../../becca/becca_service');
|
const beccaService = require('../../../becca/becca_service');
|
||||||
const utils = require('../../utils');
|
const utils = require('../../utils');
|
||||||
const log = require('../../log');
|
const log = require('../../log');
|
||||||
const scriptService = require("../../script");
|
|
||||||
const hoistedNoteService = require("../../hoisted_note");
|
const hoistedNoteService = require("../../hoisted_note");
|
||||||
|
|
||||||
function searchFromNote(note) {
|
function searchFromNote(note) {
|
||||||
@ -73,6 +72,7 @@ function searchFromRelation(note, relationName) {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const scriptService = require("../../script"); // to avoid circular dependency
|
||||||
const result = scriptService.executeNote(scriptNote, {originEntity: note});
|
const result = scriptService.executeNote(scriptNote, {originEntity: note});
|
||||||
|
|
||||||
if (!Array.isArray(result)) {
|
if (!Array.isArray(result)) {
|
||||||
|
@ -6,7 +6,7 @@ const ws = require('./ws');
|
|||||||
const taskContexts = {};
|
const taskContexts = {};
|
||||||
|
|
||||||
class TaskContext {
|
class TaskContext {
|
||||||
constructor(taskId, taskType = null, data = null) {
|
constructor(taskId, taskType = null, data = {}) {
|
||||||
this.taskId = taskId;
|
this.taskId = taskId;
|
||||||
this.taskType = taskType;
|
this.taskType = taskType;
|
||||||
this.data = data;
|
this.data = data;
|
||||||
|
12
test-etapi/import-zip.http
Normal file
12
test-etapi/import-zip.http
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
POST {{triliumHost}}/etapi/notes/root/import
|
||||||
|
Authorization: {{authToken}}
|
||||||
|
Content-Type: application/octet-stream
|
||||||
|
Content-Transfer-Encoding: binary
|
||||||
|
|
||||||
|
< ../db/demo.zip
|
||||||
|
|
||||||
|
> {%
|
||||||
|
client.assert(response.status === 201);
|
||||||
|
client.assert(response.body.note.title == "Trilium Demo");
|
||||||
|
client.assert(response.body.branch.parentNoteId == "root");
|
||||||
|
%}
|
Loading…
x
Reference in New Issue
Block a user