You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-09-16 08:56:40 +02:00
Better handling of items with same names
This commit is contained in:
@@ -82,10 +82,22 @@ class Application {
|
|||||||
|
|
||||||
async loadItems(type, pattern) {
|
async loadItems(type, pattern) {
|
||||||
let ItemClass = BaseItem.itemClass(type);
|
let ItemClass = BaseItem.itemClass(type);
|
||||||
let item = await ItemClass.loadByTitle(pattern);
|
let item = null;
|
||||||
|
if (type == BaseModel.TYPE_NOTE) {
|
||||||
|
if (!app().currentFolder()) throw new Error(_('No notebook has been created.'));
|
||||||
|
item = await ItemClass.loadFolderNoteByField(app().currentFolder().id, 'title', pattern);
|
||||||
|
} else {
|
||||||
|
item = await ItemClass.loadByTitle(pattern);
|
||||||
|
}
|
||||||
if (item) return [item];
|
if (item) return [item];
|
||||||
item = await ItemClass.load(pattern);
|
|
||||||
return [item];
|
item = await ItemClass.load(pattern); // Load by id
|
||||||
|
if (item) return [item];
|
||||||
|
|
||||||
|
item = await ItemClass.loadByPartialId(pattern);
|
||||||
|
if (item) return [item];
|
||||||
|
|
||||||
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handles the initial flags passed to main script and
|
// Handles the initial flags passed to main script and
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
import { BaseCommand } from './base-command.js';
|
import { BaseCommand } from './base-command.js';
|
||||||
import { app } from './app.js';
|
import { app } from './app.js';
|
||||||
import { _ } from 'lib/locale.js';
|
import { _ } from 'lib/locale.js';
|
||||||
|
import { BaseModel } from 'lib/base-model.js';
|
||||||
import { Folder } from 'lib/models/folder.js';
|
import { Folder } from 'lib/models/folder.js';
|
||||||
import { Note } from 'lib/models/note.js';
|
import { Note } from 'lib/models/note.js';
|
||||||
import { autocompleteItems } from './autocomplete.js';
|
import { autocompleteItems } from './autocomplete.js';
|
||||||
@@ -26,7 +27,7 @@ class Command extends BaseCommand {
|
|||||||
if (!app().currentFolder()) {
|
if (!app().currentFolder()) {
|
||||||
item = await Folder.loadByField('title', title);
|
item = await Folder.loadByField('title', title);
|
||||||
} else {
|
} else {
|
||||||
item = await Note.loadFolderNoteByField(app().currentFolder().id, 'title', title);
|
item = await app().loadItem(BaseModel.TYPE_NOTE, title);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!item) throw new Error(_('No item with title "%s" found.', title));
|
if (!item) throw new Error(_('No item with title "%s" found.', title));
|
||||||
|
@@ -5,6 +5,7 @@ import { _ } from 'lib/locale.js';
|
|||||||
import { Folder } from 'lib/models/folder.js';
|
import { Folder } from 'lib/models/folder.js';
|
||||||
import { Note } from 'lib/models/note.js';
|
import { Note } from 'lib/models/note.js';
|
||||||
import { Setting } from 'lib/models/setting.js';
|
import { Setting } from 'lib/models/setting.js';
|
||||||
|
import { BaseModel } from 'lib/base-model.js';
|
||||||
import { autocompleteItems } from './autocomplete.js';
|
import { autocompleteItems } from './autocomplete.js';
|
||||||
|
|
||||||
class Command extends BaseCommand {
|
class Command extends BaseCommand {
|
||||||
@@ -40,7 +41,7 @@ class Command extends BaseCommand {
|
|||||||
let title = args['title'];
|
let title = args['title'];
|
||||||
|
|
||||||
if (!app().currentFolder()) throw new Error(_('No active notebook.'));
|
if (!app().currentFolder()) throw new Error(_('No active notebook.'));
|
||||||
let note = await Note.loadFolderNoteByField(app().currentFolder().id, 'title', title);
|
let note = await app().loadItem(BaseModel.TYPE_NOTE, title);
|
||||||
|
|
||||||
if (!note) throw new Error(_('No note with title "%s" found.', title));
|
if (!note) throw new Error(_('No note with title "%s" found.', title));
|
||||||
|
|
||||||
|
@@ -4,6 +4,7 @@ import { _ } from 'lib/locale.js';
|
|||||||
import { Folder } from 'lib/models/folder.js';
|
import { Folder } from 'lib/models/folder.js';
|
||||||
import { Note } from 'lib/models/note.js';
|
import { Note } from 'lib/models/note.js';
|
||||||
import { autocompleteFolders } from './autocomplete.js';
|
import { autocompleteFolders } from './autocomplete.js';
|
||||||
|
import { sprintf } from 'sprintf-js';
|
||||||
|
|
||||||
class Command extends BaseCommand {
|
class Command extends BaseCommand {
|
||||||
|
|
||||||
@@ -17,7 +18,7 @@ class Command extends BaseCommand {
|
|||||||
|
|
||||||
options() {
|
options() {
|
||||||
return [
|
return [
|
||||||
['-n, --lines <num>', 'Displays only the first top <num> lines.'],
|
['-n, --limit <num>', 'Displays only the first top <num> notes.'],
|
||||||
['-s, --sort <field>', 'Sorts the item by <field> (eg. title, updated_time, created_time).'],
|
['-s, --sort <field>', 'Sorts the item by <field> (eg. title, updated_time, created_time).'],
|
||||||
['-r, --reverse', 'Reverses the sorting order.'],
|
['-r, --reverse', 'Reverses the sorting order.'],
|
||||||
['-t, --type <type>', 'Displays only the items of the specific type(s). Can be `n` for notes, `t` for todos, or `nt` for notes and todos (eg. `-tt` would display only the todos, while `-ttd` would display notes and todos.'],
|
['-t, --type <type>', 'Displays only the items of the specific type(s). Can be `n` for notes, `t` for todos, or `nt` for notes and todos (eg. `-tt` would display only the todos, while `-ttd` would display notes and todos.'],
|
||||||
@@ -36,7 +37,7 @@ class Command extends BaseCommand {
|
|||||||
let options = args.options;
|
let options = args.options;
|
||||||
|
|
||||||
let queryOptions = {};
|
let queryOptions = {};
|
||||||
if (options.lines) queryOptions.limit = options.lines;
|
if (options.limit) queryOptions.limit = options.limit;
|
||||||
if (options.sort) {
|
if (options.sort) {
|
||||||
queryOptions.orderBy = options.sort;
|
queryOptions.orderBy = options.sort;
|
||||||
queryOptions.orderByDir = 'ASC';
|
queryOptions.orderByDir = 'ASC';
|
||||||
@@ -61,6 +62,7 @@ class Command extends BaseCommand {
|
|||||||
if (options.format && options.format == 'json') {
|
if (options.format && options.format == 'json') {
|
||||||
this.log(JSON.stringify(items));
|
this.log(JSON.stringify(items));
|
||||||
} else {
|
} else {
|
||||||
|
let seenTitles = [];
|
||||||
for (let i = 0; i < items.length; i++) {
|
for (let i = 0; i < items.length; i++) {
|
||||||
let item = items[i];
|
let item = items[i];
|
||||||
let line = '';
|
let line = '';
|
||||||
@@ -68,6 +70,13 @@ class Command extends BaseCommand {
|
|||||||
line += sprintf('[%s] ', !!item.todo_completed ? 'X' : ' ');
|
line += sprintf('[%s] ', !!item.todo_completed ? 'X' : ' ');
|
||||||
}
|
}
|
||||||
line += item.title + suffix;
|
line += item.title + suffix;
|
||||||
|
|
||||||
|
if (seenTitles.indexOf(item.title) >= 0) {
|
||||||
|
line += ' (' + item.id.substr(0,4) + ')';
|
||||||
|
} else {
|
||||||
|
seenTitles.push(item.title);
|
||||||
|
}
|
||||||
|
|
||||||
this.log(line);
|
this.log(line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -29,7 +29,7 @@ class Command extends BaseCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async action(args) {
|
async action(args) {
|
||||||
let pattern = args['pattern'];
|
let pattern = args['pattern'].toString();
|
||||||
let itemType = null;
|
let itemType = null;
|
||||||
let force = args.options && args.options.force === true;
|
let force = args.options && args.options.force === true;
|
||||||
|
|
||||||
@@ -41,10 +41,10 @@ class Command extends BaseCommand {
|
|||||||
itemType = BaseModel.TYPE_NOTE;
|
itemType = BaseModel.TYPE_NOTE;
|
||||||
}
|
}
|
||||||
|
|
||||||
let item = await BaseItem.loadItemByField(itemType, 'title', pattern);
|
let item = item = await app().loadItem(itemType, pattern); // await BaseItem.loadItemByField(itemType, 'title', pattern);
|
||||||
if (!item) throw new Error(_('No item with title "%s" found.', pattern));
|
if (!item) throw new Error(_('No item with "%s" found.', pattern));
|
||||||
|
|
||||||
let ok = force ? true : await vorpalUtils.cmdPromptConfirm(this, _('Delete item?'));
|
let ok = force ? true : await vorpalUtils.cmdPromptConfirm(this, _('Delete "%s"?', item.title));
|
||||||
if (ok) {
|
if (ok) {
|
||||||
await BaseItem.deleteItem(itemType, item.id);
|
await BaseItem.deleteItem(itemType, item.id);
|
||||||
if (app().currentFolder() && app().currentFolder().id == item.id) {
|
if (app().currentFolder() && app().currentFolder().id == item.id) {
|
||||||
|
@@ -96,6 +96,11 @@ class BaseModel {
|
|||||||
return this.loadByField('id', id);
|
return this.loadByField('id', id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static loadByPartialId(partialId) {
|
||||||
|
return this.modelSelectOne('SELECT * FROM `' + this.tableName() + '` WHERE `id` LIKE ?', [partialId + '%']);
|
||||||
|
}
|
||||||
|
|
||||||
static applySqlOptions(options, sql, params = null) {
|
static applySqlOptions(options, sql, params = null) {
|
||||||
if (!options) options = {};
|
if (!options) options = {};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user